package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.business.rule.RuleBusinessLogger;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.FieldAttrEntityExt;
import com.xbongbong.paas.field.MultiUnitItemPoJo;
import com.xbongbong.paas.field.UnitItemPoJo;
import com.xbongbong.paas.help.FormDataValidateProductHelp;
import com.xbongbong.paas.help.ProSaveHelp;
import com.xbongbong.paas.help.ProUpdateHelp;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.log.pojo.InfoArrPojo;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasProcessTemplateModel;
import com.xbongbong.paas.pojo.AttrValuePojo;
import com.xbongbong.paas.pojo.FieldAttrEntityForImport;
import com.xbongbong.paas.pojo.ProductFieldPojo;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.dto.FormDataRepeatDTO;
import com.xbongbong.paas.pojo.dto.ImportFormDataDTO;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.pojo.imports.CellTitlePojo;
import com.xbongbong.paas.pojo.imports.CellValuePojo;
import com.xbongbong.paas.pojo.imports.RowGroupPojo;
import com.xbongbong.paas.pojo.vo.FormDataRepeatVO;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.service.PaasFormDataService;
import com.xbongbong.paas.service.team.TeamDataHelp;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.PageHelper;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.PageHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.bom.pojo.dto.BomBillListDTO;
import com.xbongbong.pro.bom.pojo.dto.BomDeleteBatchDTO;
import com.xbongbong.pro.bom.pojo.dto.BomEditAttrUpdateDTO;
import com.xbongbong.pro.bom.pojo.dto.BomUpdateBatchDTO;
import com.xbongbong.pro.bom.pojo.dto.BomUpdateByBusinessRuleDTO;
import com.xbongbong.pro.bom.pojo.dto.BomUpdateDTO;
import com.xbongbong.pro.bom.pojo.vo.BomDeleteBatchVO;
import com.xbongbong.pro.bomproduct.pojo.dto.BomProductDeleteBatchDTO;
import com.xbongbong.pro.bomproduct.pojo.dto.FormatBomProductDTO;
import com.xbongbong.pro.bomuser.pojo.dto.BomUserDeleteBatchDTO;
import com.xbongbong.pro.businessdata.pojo.dto.BusinessDataDTO;
import com.xbongbong.pro.businessproduct.pojo.dto.BusinessProductListDTO;
import com.xbongbong.pro.businessproduct.pojo.vo.BusinessProductListVO;
import com.xbongbong.pro.common.pojo.dto.RepeatCommonConditionDTO;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.customer.pojo.dto.ChangeStatusDTO;
import com.xbongbong.pro.detailtab.vo.ProductSummaryVO;
import com.xbongbong.pro.domain.entity.FormConfigEntity;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.UserTeamErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.AfterSavePojo;
import com.xbongbong.pro.listbatch.pojo.dto.AddLabelDTO;
import com.xbongbong.pro.log.pojo.dto.RuleBusinessLogDTO;
import com.xbongbong.pro.product.pojo.dto.PagingProductDTO;
import com.xbongbong.pro.product.pojo.dto.ProductExplainDTO;
import com.xbongbong.pro.product.pojo.vo.DetailProductVO;
import com.xbongbong.pro.product.pojo.vo.PagingProductVO;
import com.xbongbong.pro.productionorderproduct.pojo.dto.FormatProductionOrderProductDTO;
import com.xbongbong.saas.analytical.impl.BomBillValidateAnalyticalServiceImpl;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ErrorMessageConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.ProductConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.BomProductEntity;
import com.xbongbong.saas.domain.entity.BomUserEntity;
import com.xbongbong.saas.domain.entity.ContractProductEntity;
import com.xbongbong.saas.domain.entity.SmartReplenishmentEntity;
import com.xbongbong.saas.domain.entity.ext.BomBillEntityExt;
import com.xbongbong.saas.domain.entity.ext.ProductEntityExt;
import com.xbongbong.saas.domain.entity.ext.ProductionOrderProductEntityExt;
import com.xbongbong.saas.enums.BusinessProductEnum;
import com.xbongbong.saas.enums.ContractProduceEnum;
import com.xbongbong.saas.enums.FormConfigEnum;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.RelativeProductEnum;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.UpdateDataTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.BomBillEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.ProductionOrderEnum;
import com.xbongbong.saas.enums.product.BomFinishProductEnum;
import com.xbongbong.saas.enums.product.BomMaterielProductEnum;
import com.xbongbong.saas.enums.product.ProductionOrderMaterielProductEnum;
import com.xbongbong.saas.help.ExplainHelp;
import com.xbongbong.saas.help.FieldAttrHelp;
import com.xbongbong.saas.help.ImportHelper;
import com.xbongbong.saas.help.LogHandleHelp;
import com.xbongbong.saas.help.RelativeProductHelp;
import com.xbongbong.saas.help.SaasFormHelp;
import com.xbongbong.saas.help.SaasGetHelp;
import com.xbongbong.saas.help.SaasSaveHelp;
import com.xbongbong.saas.help.SaasUpdateHelp;
import com.xbongbong.saas.model.BomBillModel;
import com.xbongbong.saas.model.BomProductModel;
import com.xbongbong.saas.model.BomUserModel;
import com.xbongbong.saas.model.ContractProductModel;
import com.xbongbong.saas.model.FormConfigModel;
import com.xbongbong.saas.model.ProductModel;
import com.xbongbong.saas.model.SmartReplenishmentModel;
import com.xbongbong.saas.model.SpecificationModel;
import com.xbongbong.saas.service.BomBillService;
import com.xbongbong.saas.service.BomProductService;
import com.xbongbong.saas.service.BomUserService;
import com.xbongbong.saas.service.ProductService;
import com.xbongbong.saas.service.ProductionOrderService;
import com.xbongbong.saas.service.UserTeamService;
import com.xbongbong.saas.service.toolbox.help.LogHelp;
import com.xbongbong.saas.service.toolbox.help.ProductHelp;
import com.xbongbong.saas.service.toolbox.help.UserTeamHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserModel;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;

import static com.xbongbong.saas.enums.RelativeProductEnum.ATTRITION_RATE;
import static com.xbongbong.saas.enums.RelativeProductEnum.BARCODE;
import static com.xbongbong.saas.enums.RelativeProductEnum.NAME;
import static com.xbongbong.saas.enums.RelativeProductEnum.NUM;
import static com.xbongbong.saas.enums.RelativeProductEnum.PRODUCT_NO;
import static com.xbongbong.saas.enums.RelativeProductEnum.SPECIFICATION;
import static com.xbongbong.saas.enums.RelativeProductEnum.UNIT;
import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getDoubleOrDefaultFromFormData;
import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getIntegerFromFormData;
import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getIntegerOrDefaultFromFormData;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;


/**
 * BOM单service实现层
 *
 * @author long.rao
 * @version v1.0
 * @date 2019/1/22 11:08
 * @since v1.0
 */
@Service("bomBillService")
public class BomBillServiceImpl implements BomBillService {

    private static final Logger LOG = LoggerFactory.getLogger(BomBillServiceImpl.class);

    @Resource
    private BomBillModel bomBillModel;
    @Resource
    private SaasUpdateHelp saasUpdateHelp;
    @Resource
    private SaasSaveHelp saasSaveHelp;
    @Resource
    private UserModel userModel;
    @Resource
    private BomUserModel bomUserModel;
    @Resource
    private ProductModel productModel;
    @Resource
    private BomProductModel bomProductModel;
    @Resource
    private SpecificationModel specificationModel;
    @Resource
    private EsHelper esHelper;
    @Resource
    private ExplainHelp explainHelp;
    @Resource
    private BomUserService bomUserService;
    @Resource
    private BomProductService bomProductService;
    @Resource
    private ProductionOrderService productionOrderService;
    @Resource
    private FieldAttrHelp fieldAttrHelp;
    @Resource
    private ProductService productService;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private ImportHelper importHelper;
    @Resource
    private ProductHelp productHelp;
    @Resource
    private SaasGetHelp saasGetHelp;
    @Resource
    private PaasProcessTemplateModel paasProcessTemplateModel;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private UserTeamService userTeamService;
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    @Lazy
    private RuleBusinessLogger ruleBusinessLogger;
    @Resource
    private FormDataValidateProductHelp formDataValidateProductHelp;
    @Resource
    private PaasFormDataService paasFormDataService;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private ProUpdateHelp proUpdateHelp;
    @Resource
    private SaasFormHelp saasFormHelp;
    @Resource
    private RelativeProductHelp relativeProductHelp;
    @Resource
    private LogHelp logHelp;
    @Resource
    private LogHandleHelp logHandleHelp;
    @Resource
    private ContractProductModel contractProductModel;
    @Resource
    private FormConfigModel formConfigModel;
    @Resource
    private BomBillValidateAnalyticalServiceImpl bomBillAnalyticalService;
    @Resource
    private TeamDataHelp teamDataHelp;
    @Resource
    private SmartReplenishmentModel smartReplenishmentModel;
    @Resource
    private UserTeamHelp userTeamHelp;

    /**
     * Bom清单保存前saas特殊校验
     *
     * @param validateDataDTO saas特殊校验数据入参
     * @throws XbbException 业务异常
     * @author long.rao
     * @date 2019-01-23 10:13
     */
    @Override
    public void beforeSave(ValidateDataDTO validateDataDTO) throws XbbException {
        bomBillAnalyticalService.beforeSave(validateDataDTO);
     }

    /**
     * Bom清单保存后逻辑
     *
     * @param saasFormSaveDTO saas保存数据
     * @throws XbbException 业务异常
     * @author long.rao
     * @date 2019-01-29 21:18
     */
    @Override
    public AfterSavePojo afterSave(SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        String corpid = saasFormSaveDTO.getCorpid();
        PaasFormDataEntity newEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
        Long bomId = newEntity.getId();

        // 团队保存
        AfterSavePojo afterSavePojo = teamDataHelp.saveUserTeam(saasFormSaveDTO.getSaasNeedRedundantAttrPoJo(), bomId, saasFormSaveDTO.getNewPaasFormDataEntity(), saasFormSaveDTO.getIsImport(), false);

//        userTeamService.saveUserTeam(saasFormSaveDTO);

        // 保存bom单关联产品
        JSONObject dataList = newEntity.getData();
        Boolean productCanSee = saasFormSaveDTO.getSaasNeedRedundantAttrPoJo().getAttrCanSee(BomBillEnum.PRODUCT.getAttr());
        Boolean materielCanSee = saasFormSaveDTO.getSaasNeedRedundantAttrPoJo().getAttrCanSee(BomBillEnum.MATERIEL.getAttr());
        saveProduct2(dataList,corpid,bomId,productCanSee,materielCanSee);
        return afterSavePojo;
    }

    private void saveProduct2(JSONObject data, String corpid, Long bomId, Boolean productCanSee, Boolean materielCanSee) throws XbbException {
        Map<Long,BomProductEntity> originProductMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<BomProductEntity> originProductEntities = bomProductModel.getProductsByBomId(bomId, corpid, null, Arrays.asList(DelEnum.NORMAL.getDel(), DelEnum.APPROVE_FAILED.getDel()));
        BomProductEntity finishProductEntity = null;
        for (BomProductEntity entity : originProductEntities){
            originProductMap.put(entity.getId(), entity);

            if (Objects.equals(entity.getType(),1)){
                finishProductEntity = entity;
            }
        }
        JSONArray finishProductArray = data.getJSONArray(BomBillEnum.PRODUCT.getAttr());
        JSONArray materielProductArray = data.getJSONArray(BomBillEnum.MATERIEL.getAttr());
        JSONArray productArray = new JSONArray();
        productArray.addAll(finishProductArray);
        productArray.addAll(materielProductArray);
        Map<Long, PaasFormDataEntityExt> productMap = formDataValidateProductHelp.product2saveMap(corpid,productArray);
        Integer sort = 0;
        List<BomProductEntity> insertList = new ArrayList<>();
        List<BomProductEntity> updateList = new ArrayList<>();
        if (productCanSee) {
            for (int i = 0; i < finishProductArray.size(); i++) {
                JSONObject jsonObject = finishProductArray.getJSONObject(i);
                Long pageProductId = jsonObject.getLong(SelectProductEnum.PRODUCT.getAttr());
                Long businessProductId = jsonObject.getLong(BusinessConstant.PRODUCT_SUB_ID);
                boolean addProductFlag = formDataValidateProductHelp.addProductFlag(businessProductId);                sort++;
                Double productNum = jsonObject.getDouble(BomFinishProductEnum.NUM.getAttr());
                BomProductEntity bomProductEntity;
                if (addProductFlag) {
                    bomProductEntity = new BomProductEntity();
                    bomProductEntity.setAddTime(DateTimeUtil.getInt());
                    bomProductEntity.setUpdateTime(DateTimeUtil.getInt());
                    insertList.add(bomProductEntity);
                } else if (originProductMap.containsKey(businessProductId)) {
                    bomProductEntity = originProductMap.get(businessProductId);
                    bomProductEntity.setUpdateTime(DateTimeUtil.getInt());
                    if (Objects.equals(DelEnum.APPROVE_FAILED.getDel(), bomProductEntity.getDel())) {
                        bomProductEntity.setDel(DelEnum.NORMAL.getDel());
                    }
                    updateList.add(bomProductEntity);
                    originProductMap.remove(businessProductId);
                } else {
                    continue;
                }
                JSONObject productData = productMap.get(pageProductId).getData();
                bomProductEntity.setCorpid(corpid);
                bomProductEntity.setParentId(productData.getLong(ProductEnum.PARENT_ID.getAttr()));
                bomProductEntity.setProductId(pageProductId);
                bomProductEntity.setProductNum(productNum);
                bomProductEntity.setAttritionRate(0D);
                bomProductEntity.setProductName(productData.getString(ProductEnum.NAME.getAttr()));
                // 保存的是父产品的编号
                bomProductEntity.setProductNo(productData.getString(ProductEnum.PRODUCT_NO.getAttr()));
                bomProductEntity.setProductSpecification(productData.getString(ProductEnum.SPECIFICATION_LINK_TEXT.getAttr()));
                bomProductEntity.setType(1);
                bomProductEntity.setSort(sort);
                bomProductEntity.setBomId(bomId);
                bomProductEntity.setMemo(jsonObject.getString(SelectProductEnum.MEMO.getAttr()));
                bomProductEntity.setBarcode(productData.getString(ProductEnum.BARCODE.getAttr()));
                Integer enableMultiUnit = productData.getInteger(ProductEnum.ENABLE_MULTI_UNIT.getAttr());
                if (Objects.equals(enableMultiUnit, 1)) {
                    formDataValidateProductHelp.setBusinessUnit(jsonObject, bomProductEntity);
                    bomProductEntity.setProductUnit(jsonObject.getString(SelectProductEnum.UNIT.getAttr()));
                } else {
                    bomProductEntity.setProductUnit(productData.getString(ProductEnum.UNIT.getAttr()));
                    jsonObject.put(SelectProductEnum.UNIT.getAttr(),productData.getString(ProductEnum.UNIT.getAttr()));
                }
                bomProductEntity.setData(jsonObject);
                Integer isDefault = getIntegerFromFormData(data, BomBillEnum.VERSION_LINK_TEXT.getAttr());
                if (isDefault != null && Objects.equals(isDefault, 1)) {
                    checkBomAndFinshedProduct(corpid, pageProductId,bomId);
                }
            }
        }else {
            Integer isDefault = getIntegerFromFormData(data, BomBillEnum.VERSION_LINK_TEXT.getAttr());
            if (isDefault != null && Objects.equals(isDefault, 1)) {
                if (Objects.nonNull(finishProductEntity)){
                    checkBomAndFinshedProduct(corpid, finishProductEntity.getProductId(),bomId);
                }
            }
        }
        if (materielCanSee) {
            for (int i = 0; i < materielProductArray.size(); i++) {
                JSONObject jsonObject = materielProductArray.getJSONObject(i);
                Long pageProductId = jsonObject.getLong(SelectProductEnum.PRODUCT.getAttr());
                Long businessProductId = jsonObject.getLong(BusinessConstant.PRODUCT_SUB_ID);
                boolean addProductFlag = formDataValidateProductHelp.addProductFlag(businessProductId);                sort++;
                Double productNum = jsonObject.getDouble(BomMaterielProductEnum.NUM.getAttr());
                Double lossRate = jsonObject.getDouble(BomMaterielProductEnum.LOSS_RATE.getAttr());
                lossRate = Objects.isNull(lossRate) ? 0D : lossRate;
                BomProductEntity bomProductEntity;
                if (addProductFlag) {
                    bomProductEntity = new BomProductEntity();
                    bomProductEntity.setAddTime(DateTimeUtil.getInt());
                    bomProductEntity.setUpdateTime(DateTimeUtil.getInt());
                    insertList.add(bomProductEntity);
                } else if (originProductMap.containsKey(businessProductId)) {
                    bomProductEntity = originProductMap.get(businessProductId);
                    bomProductEntity.setUpdateTime(DateTimeUtil.getInt());
                    if (Objects.equals(DelEnum.APPROVE_FAILED.getDel(), bomProductEntity.getDel())) {
                        bomProductEntity.setDel(DelEnum.NORMAL.getDel());
                    }
                    updateList.add(bomProductEntity);
                    originProductMap.remove(businessProductId);
                }  else {
                    continue;
                }
                JSONObject productData = productMap.get(pageProductId).getData();
                bomProductEntity.setCorpid(corpid);
                bomProductEntity.setParentId(productData.getLong(ProductEnum.PARENT_ID.getAttr()));
                bomProductEntity.setProductId(pageProductId);
                bomProductEntity.setProductNum(productNum);
                bomProductEntity.setAttritionRate(lossRate);
                bomProductEntity.setProductName(productData.getString(ProductEnum.NAME.getAttr()));
                // 保存的是父产品的编号
                bomProductEntity.setProductNo(productData.getString(ProductEnum.PRODUCT_NO.getAttr()));
                bomProductEntity.setProductSpecification(productData.getString(ProductEnum.SPECIFICATION_LINK_TEXT.getAttr()));
                bomProductEntity.setType(2);
                bomProductEntity.setSort(sort);
                bomProductEntity.setBomId(bomId);
                bomProductEntity.setMemo(jsonObject.getString(SelectProductEnum.MEMO.getAttr()));
                bomProductEntity.setBarcode(productData.getString(ProductEnum.BARCODE.getAttr()));
                Integer enableMultiUnit = productData.getInteger(ProductEnum.ENABLE_MULTI_UNIT.getAttr());
                if (Objects.equals(enableMultiUnit, 1)) {
                    formDataValidateProductHelp.setBusinessUnit(jsonObject, bomProductEntity);
                    bomProductEntity.setProductUnit(jsonObject.getString(SelectProductEnum.UNIT.getAttr()));
                } else {
                    bomProductEntity.setProductUnit(productData.getString(ProductEnum.UNIT.getAttr()));
                    jsonObject.put(SelectProductEnum.UNIT.getAttr(),productData.getString(ProductEnum.UNIT.getAttr()));
                }
                bomProductEntity.setData(jsonObject);
            }
        }
        bomProductModel.insertBatch(insertList);

        bomProductModel.updateBatch(updateList, corpid);
        List<Long> deleteList = new ArrayList<>();
        for (Map.Entry<Long, BomProductEntity> entry : originProductMap.entrySet()) {
            BomProductEntity delProduct = entry.getValue();
            delProduct.setDel(1);
            deleteList.add(delProduct.getId());
        }
        bomProductModel.deleteByIdIn(deleteList, corpid);
        // 状态
        String status = BomBillEnum.STATUS.getAttr();
        if (data.containsKey(status)){
            // 获取[新建合同订单缺货时自动更新]表单配置
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(ParameterConstant.CORPID, corpid);
            param.put("config", FormConfigEnum.PRODUCTION_ORDER_AUTO_UPDATE_NEW_CONTRACT.getConfig());
            List<FormConfigEntity> formConfigList = formConfigModel.findEntitys(param);
            if(CollectionUtils.isNotEmpty(formConfigList)){
                // 代表该合同产品是显示在待生产列表还是待采购列表，1：待生产列表；0：待采购列表，默认0
                // bom禁用是状态标记为0
                int isProduce = "0".equals(data.get(status)) ? 0 : 1;
                // 同一个公司同一个配置选择应当只有一个
                FormConfigEntity formConfigEntity = formConfigList.get(0);
                // 只有勾选了才进这段才会进生产单,没勾选不管bom启用还是禁用都去待采购列表
                if(StringUtils.equals(formConfigEntity.getConfigValue(), "0")){
                    isProduce = 0;
                }
                // 更新合同产品数据
                List<Long> productIdList = new ArrayList<>();
                for (int i = 0; i < finishProductArray.size(); i++) {
                    JSONObject jsonObject = finishProductArray.getJSONObject(i);
                    productIdList.add(jsonObject.getLong(SelectProductEnum.PRODUCT.getAttr()));
                }
                // 更新智能补货数量 必须在更新合同产品之前执行
                Map<String, Object> contParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                contParam.put(ParameterConstant.CORPID, corpid);
                contParam.put("productIdIn", productIdList);
                contParam.put("del", 0);
                if (Objects.equals(isProduce,1)){
                    // 如果产品从待采购变为待生产 则需要先从数据库中查询出这些产品的所有数量
                    // 当前待采购的有多少 就有多少是需要变更为待生产的  智能补货需要减去这一部分
                    // 是待采购的才计入
                    contParam.put("isProduce", ContractProduceEnum.WAIT_PURCHASE.getCode());
                }else {
                    // 如果产品从待生产变为待采购 则需要先从数据库中查询出这些产品的所有数量
                    // 当前待生产的有多少 就有多少是需要变更为待采购的  智能补货需要减去这一部分
                    // 是待生产的才计入
                    contParam.put("isProduce", ContractProduceEnum.WAIT_PRODUCE.getCode());
                }
                List<ContractProductEntity> contractProductList = contractProductModel.findEntitys(contParam);
                if (CollectionUtils.isNotEmpty(contractProductList)){
                    Map<Long,Double> productNumMap = new HashMap<>();
                    Map<Long,Double> outNumMap = new HashMap<>();
                    for (ContractProductEntity contractProductEntity : contractProductList) {
                        Long productId = contractProductEntity.getProductId();
                        Double productNum = contractProductEntity.getProductNum();
                        Double outstockNum = contractProductEntity.getOutstockNum();
                        if (productNumMap.containsKey(productId)){
                            productNumMap.put(productId,Arith.add(productNumMap.get(productId),productNum));
                        }else {
                            productNumMap.put(productId,productNum);
                        }
                        if (outNumMap.containsKey(productId)){
                            outNumMap.put(productId,Arith.add(outNumMap.get(productId),outstockNum));
                        }else {
                            outNumMap.put(productId,outstockNum);
                        }
                    }
                    // 封装未出库数量
                    Map<Long,Double> waitOutNumMap = new HashMap<>();
                    for (Map.Entry<Long, Double> entry : productNumMap.entrySet()) {
                        Long productId = entry.getKey();
                        Double productNum = entry.getValue();
                        Double outNum = outNumMap.getOrDefault(productId, 0D);
                        waitOutNumMap.put(productId,Arith.sub(productNum,outNum));
                    }
                    List<SmartReplenishmentEntity> smartReplenishmentEntityList = smartReplenishmentModel.getByProductList(corpid, productIdList);
                    if (CollectionUtils.isNotEmpty(smartReplenishmentEntityList)){
                        for (SmartReplenishmentEntity smartReplenishmentEntity : smartReplenishmentEntityList) {
                            Double waitOutstockNum = smartReplenishmentEntity.getWaitOutstockNum();
                            Long productId = smartReplenishmentEntity.getProductId();
                            Double changeNum = waitOutNumMap.getOrDefault(productId, 0D);
                            if (Objects.equals(isProduce,1)){
                                smartReplenishmentEntity.setWaitOutstockNum(Arith.sub(waitOutstockNum,changeNum));
                            }else {
                                smartReplenishmentEntity.setWaitOutstockNum(Arith.add(waitOutstockNum,changeNum));
                            }
                        }
                        smartReplenishmentModel.updateBatch(smartReplenishmentEntityList,corpid);
                    }
                }
                contractProductModel.updateIsProduceByProductId(isProduce, corpid, productIdList);
            }
        }
    }

    @Override
    public void saveProduct(JSONArray productArray, Integer productType, String corpid, Long bomId) throws XbbException {
        if (productArray == null || corpid == null || bomId == null) {
            return;
        }
        List<Long> pageProductIds = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        pageProductIds.add(-1L);
        List<Long> dbProductIds = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        dbProductIds.add(-1L);
        List<Long> addProductIds = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        addProductIds.add(-1L);
        List<Long> deleteProductIds = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        deleteProductIds.add(-1L);
        List<BomProductEntity> updateProducts = new ArrayList<>();
        for (int i = 0; i < productArray.size(); i++) {
            JSONObject jsonObject = productArray.getJSONObject(i);
            // 页面传入的产品id
            Long productId = jsonObject.getLong(StringConstant.SAAS_LINK_BUSINESS_ID);
            pageProductIds.add(productId);
        }

        // 获取原BOM单的关联产品
        List<BomProductEntity> bomProducts = bomProductModel.getProductsByBomId(bomId, corpid, productType);
        for (BomProductEntity bomProduct : bomProducts) {
            // 数据库中原来的产品id
            dbProductIds.add(bomProduct.getProductId());
        }
        // 新增
        for (Long productId : pageProductIds) {
            if (!dbProductIds.contains(productId)) {
                addProductIds.add(productId);
            }
        }

        // 刪除
        for (BomProductEntity bomProduct : bomProducts) {
            if (!pageProductIds.contains(bomProduct.getProductId())) {
                bomProduct.setDel(DelEnum.DELETE.getDel());
                bomProduct.setUpdateTime(DateTimeUtil.getInt());
                bomProductModel.update(bomProduct);
                deleteProductIds.add(bomProduct.getProductId());
            }
        }

        // 编辑
        for (BomProductEntity bomProduct : bomProducts) {
            if (!deleteProductIds.contains(bomProduct.getProductId())) {
                updateProducts.add(bomProduct);
            }
        }

        // 新增的时候，冗余保存产品的name和编号，规格等信息
        List<String> fieldList = Arrays.asList(StringConstant.SAAS_LINK_BUSINESS_ID, StringConstant.DATA_ID, StringConstant.JSON_DATA);
        Map<String, Map<Long, ProductEntityExt>> resultMap = productModel.getProductWithParentMapByIdIn(corpid, addProductIds, fieldList);
        Map<Long, ProductEntityExt> productMap = resultMap.get(StringConstant.PRODUCT_MAP);
        Map<Long, ProductEntityExt> parentProductMap = resultMap.get(StringConstant.PARENT_PRODUCT_MAP);

        // 产品排序
        Integer sort = 0;
        for (int i = 0; i < productArray.size(); i++) {
            JSONObject jsonObject = productArray.getJSONObject(i);
            sort++;
            // 页面传入的产品id
            Long pageProductId = jsonObject.getLong(StringConstant.SAAS_LINK_BUSINESS_ID);
            for (Long productId : addProductIds) {
                if (Objects.equals(pageProductId, productId)) {
                    BomProductEntity bomProductEntity = new BomProductEntity();
                    if (productMap.containsKey(productId)) {
                        ProductEntityExt product = productMap.get(productId);
                        JSONObject dataList =  product.getData();
                        ProductEntityExt parentProduct = parentProductMap.get(dataList.getLong(ProductEnum.PARENT_ID.getAttr()));
                        String productNo = "";
                        if (parentProduct != null) {
                            JSONObject parentDataList = parentProduct.getData();
                            productNo = parentDataList.getString(ProductEnum.PRODUCT_NO.getAttr());
                        }
                        // 产品数量
                        Double productNum = 1D;
                        if (Objects.equals(productType, 2)) {
                            productNum = jsonObject.getDouble(RelativeProductEnum.NUM.getSaasAttr());
                        }
                        Double attrition = 0D;
                        if (Objects.equals(productType, 2)) {
                            // 产品损耗率
                            attrition = jsonObject.getDouble(RelativeProductEnum.ATTRITION_RATE.getSaasAttr());
                        }
                        bomProductEntity.setCorpid(corpid);
                        bomProductEntity.setParentId(product.getData().getLong(ProductEnum.PARENT_ID.getAttr()));
                        bomProductEntity.setProductId(productId);
                        bomProductEntity.setProductNum(productNum);
                        bomProductEntity.setAttritionRate(attrition);
                        bomProductEntity.setProductName(dataList.getString(ProductEnum.NAME.getAttr()));
                        // 保存的是父产品的编号
                        bomProductEntity.setProductNo(productNo);
                        bomProductEntity.setProductSpecification(dataList.getString(ProductEnum.SPECIFICATION_LINK_TEXT.getAttr()));
                        bomProductEntity.setProductUnit(dataList.getString(ProductEnum.UNIT.getAttr()));
                        bomProductEntity.setType(productType);
                        bomProductEntity.setSort(sort);
                        bomProductEntity.setBomId(bomId);
                        bomProductEntity.setBarcode(dataList.getString(ProductEnum.BARCODE.getAttr()));
                        bomProductModel.save(bomProductEntity);
                    }
                    break;
                }
            }

            for (BomProductEntity bomProduct : updateProducts) {
                if (Objects.equals(bomProduct.getProductId(), pageProductId)) {
                    Double productNum;
                    try {
                        productNum = jsonObject.getDouble(RelativeProductEnum.NUM.getSaasAttr());
                    } catch (Exception e) {
                        productNum = 0D;
                    }
                    long now = DateTimeUtil.getInt();
                    bomProduct.setProductNum(productNum);
                    Double attritionRate = jsonObject.getDouble(RelativeProductEnum.ATTRITION_RATE.getSaasAttr());
                    bomProduct.setAttritionRate(attritionRate == null ? 0D : attritionRate);
                    bomProduct.setType(productType);
                    bomProduct.setUpdateTime(now);
                    bomProduct.setSort(sort);
                    bomProductModel.save(bomProduct);
                    break;
                }
            }
        }
    }

//    @Override
//    public void formatProduct4Show(JSONObject dataList, SaasAnalysisDataDTO saasAnalysisDataDTO) throws XbbException {
//        if (dataList == null || saasAnalysisDataDTO == null) {
//            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028);
//        }
//        // 获取生产单关联产品
//        BusinessProductListDTO businessProductListDTO = new BusinessProductListDTO();
//        BeanUtil.copyProperties(saasAnalysisDataDTO, businessProductListDTO);
//        BusinessProductListVO businessProductListVO;
//        if (saasAnalysisDataDTO.getForProcess()) {
//            businessProductListVO = getBomProductList(businessProductListDTO, dataList);
//        } else {
//            businessProductListVO = getBomProductList(businessProductListDTO, null);
//        }
//        JSONObject finishedProductObj = businessProductListVO.getFinishedProduct();
//        JSONObject materielProductObj = businessProductListVO.getMateriel();
//        dataList.put(BomBillEnum.PRODUCT.getAttr(), finishedProductObj);
//        dataList.put(BomBillEnum.MATERIEL.getAttr(), materielProductObj);
//    }

    public JSONObject getFormatProductJsonArray(FormatBomProductDTO formatBomProductDTO, Map<Long, ProductEntityExt> productMap) throws XbbException {
        // 获取参数
        BomProductEntity bomProductEntity = formatBomProductDTO.getBomProductEntity();
        Long productId = bomProductEntity.getProductId();
        PaasFormDataEntityExt productEntity = productMap.get(productId);

        Map<String, FieldAttrEntity> nowProductExplainMap = formatBomProductDTO.getNowProductExplainMap();

        JSONObject productObj = new JSONObject();
        JSONArray attrArray = new JSONArray();

        // 获取关联产品需要展示的字段
        BusinessProductEnum businessProductEnum = BusinessProductEnum.getByCode(XbbRefTypeEnum.BOM_BILL.getCode());

        if (businessProductEnum != BusinessProductEnum.UNKNOW) {
            List<RelativeProductEnum> businessProductEnumList = businessProductEnum.getList();
            Integer productType = bomProductEntity.getType();

            for (RelativeProductEnum productEnum : businessProductEnumList) {
                String saasAttr = productEnum.getSaasAttr();
                FieldAttrEntity fieldAttrEntity = null;
                if (nowProductExplainMap.containsKey(saasAttr)) {
                    fieldAttrEntity = nowProductExplainMap.get(saasAttr);
                }
                switch (productEnum) {
                    case NAME:
                        JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(NAME, bomProductEntity.getProductName(), fieldAttrEntity));
                        break;
                    case PRODUCT_NO:
                        JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(PRODUCT_NO, bomProductEntity.getProductNo(), fieldAttrEntity));
                        break;
                    case BARCODE:
                        String barcode = bomProductEntity.getBarcode();
                        barcode = barcode == null ? "" : barcode;
                        JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(BARCODE, barcode, fieldAttrEntity));
                        break;
                    case SPECIFICATION:
                        // 格式化规格
                        String specification = specificationModel.joinSpecification(bomProductEntity.getProductSpecification());
                        JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(SPECIFICATION, specification, fieldAttrEntity));
                        break;
                    case NUM:
                        Double num = bomProductEntity.getProductNum();
                        num = num == null ? 0 : num;
                        JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(NUM, num, fieldAttrEntity));
                        break;
                    case UNIT:
                        String productUnit = bomProductEntity.getProductUnit();
                        String unitStr = fieldAttrHelp.getDataDictionaryTextByValue(productUnit, fieldAttrEntity);
                        JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(UNIT, unitStr, fieldAttrEntity));
                        break;
                    case ATTRITION_RATE:
                        if (Objects.equals(productType, 2)) {
                            // 物料产品才有损耗率
                            JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(ATTRITION_RATE, bomProductEntity.getAttritionRate(), fieldAttrEntity));
                        }
                        break;
                    case THUMBNAIL:
                        JSONArray defaultImage = productEntity.getData().getJSONArray(ProductEnum.PRODUCT_IMGS.getAttr());
                        JSONArray imageList = bomProductEntity.getImageUrlArray() == null ? defaultImage : bomProductEntity.getImageUrlArray();
                        productObj.put(ProductEnum.THUMBNAIL.getSaasAttr(), imageList);
                        break;
                    default:
                        break;
                }
            }
        }
        productObj.put("result", attrArray);
        productObj.put(StringConstant.SAAS_LINK_BUSINESS_ID, productId);
        productObj.put(StringConstant.BUSINESS_PRODUCT_ID, bomProductEntity.getId());
        productObj.put("parentId", bomProductEntity.getParentId());
        // TODO 库存产品自定义字段的回显
        return productObj;
    }

    @Override
    public void formatProduct4Show2(Long dataId, String corpid, JSONObject data, UpdateDataTypeEnum updateDataTypeEnum) throws XbbException {
        bomBillModel.formatProduct4Show2(dataId, corpid, data, updateDataTypeEnum);
    }

    @Override
    public JSONObject formatSingleProduct(BomProductEntity bomProductEntity) {
        return bomBillModel.formatSingleProduct(bomProductEntity);
    }

    @Override
    public JSONObject formatSingleMaterial(BomProductEntity bomProductEntity) {
        JSONObject json = bomProductEntity.getData();
        if (Objects.equals(bomProductEntity.getType(),2)) {
            if (Objects.isNull(json) || json.isEmpty()) {
                json = new JSONObject();
                for (ProductionOrderMaterielProductEnum productionOrderMaterielProductEnum : ProductionOrderMaterielProductEnum.values()) {
                    String attr = productionOrderMaterielProductEnum.getAttr();
                    switch (productionOrderMaterielProductEnum){
                        case PRODUCT:
                            json.put(attr,bomProductEntity.getProductId());
                            break;
                        case NUM:
                            json.put(attr,bomProductEntity.getProductNum());
                            break;
                        case MEMO:
                            json.put(attr,bomProductEntity.getMemo());
                            break;
                        case LOSS_RATE:
                            json.put(attr,bomProductEntity.getAttritionRate());
                            break;
                        case UNIT:
                            json.put(attr,bomProductEntity.getProductUnit());
                            break;
                        default:
                            break;
                    }
                }
            }
        }
        return json;
    }

    @Override
    public BusinessProductListVO getBomProductList(BusinessProductListDTO businessProductListDTO, JSONObject dataList) throws XbbException {
        // 获取参数
        String corpid = businessProductListDTO.getCorpid();
        String userId = businessProductListDTO.getUserId();
        UserEntity userEntity = userModel.getByKey(userId, corpid);
        Integer sourceBusinessType = businessProductListDTO.getSourceBusinessType();
        Long bomId = businessProductListDTO.getDataId();
        boolean detailGet = businessProductListDTO.getDetailGet();
        // 待生产时会有值
        JSONArray finishedProductArray = businessProductListDTO.getFinishedProductArray();

        List<BomProductEntity> bomProductList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        // 流程数据没有bomId，需要重新组装bomProductList
        Map<String, Object> modelMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        modelMap.put(ParameterConstant.PAGE, businessProductListDTO.getPage());
        modelMap.put(StringConstant.CORPID, corpid);
        modelMap.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        modelMap.put("bomIdIn", Collections.singletonList(bomId));
        PageHelper pageHelper = PageHelperUtil.getPageHelper(modelMap, bomProductModel, businessProductListDTO.getPageSize());
        if (businessProductListDTO.getForProcess()) {
            // 获取成品产品列表
            JSONArray productArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(FastJsonHelper.getJsonObjectOrDefaultFromFormData(dataList, BomBillEnum.PRODUCT.getAttr(), new JSONObject()), StringConstant.PRODUCT_LIST, new JSONArray());
            Map<Long, ProductEntityExt> productMap = productModel.getProductMap(corpid, productArray);
            bomBillModel.formatProductList(corpid, bomProductList, productArray, productMap, 1);
            // 获取物料产品列表
            JSONArray materielArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(FastJsonHelper.getJsonObjectOrDefaultFromFormData(dataList, BomBillEnum.MATERIEL.getAttr(), new JSONObject()), StringConstant.PRODUCT_LIST, new JSONArray());
            Map<Long, ProductEntityExt> materielMap = productModel.getProductMap(corpid, materielArray);
            bomBillModel.formatProductList(corpid, bomProductList, materielArray, materielMap, 2);
        } else {
            // 获取bom单关联产品，成品和物料
            //bomProductList = bomProductModel.getProductsByBomId(bomId, corpid, null);
            bomProductList = productHelp.getBomProducts(Collections.singletonList(bomId), corpid, null, pageHelper);
        }

        List<Long> productIds = new ArrayList<>();
        productIds.add(-1L);
        bomProductList.forEach(item -> {
            productIds.add(item.getProductId());
        });
        // 根据productIdIn获取对应产品信息
        Map<Long, ProductEntityExt> productMap = productModel.getProductMapByIdIn(corpid, productIds, null);
        // 用于存放当前启用的产品模板解释的map
        Map<String, FieldAttrEntity> nowProductExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        explainHelp.getRelativeProductExplainsFromDB(corpid, nowProductExplainMap, null);

        Double fProductNum = 1D;
        if (finishedProductArray != null && finishedProductArray.size() > 0) {
            // 待生产，成品数量是前端传入的数量
            JSONObject jsonObject = finishedProductArray.getJSONObject(0);
            fProductNum = jsonObject.getDouble(StringConstant.NUM);
        }

        // 返回给前端的接受对象
        // 成品产品对象
        JSONObject productFinalObj = new JSONObject();
        // 物料产品对象
        JSONObject materielProductFinalObj = new JSONObject();
        // 成品产品数组
        JSONArray productArray = new JSONArray();
        // 物料产品数组
        JSONArray materielProductArray = new JSONArray();
        // 物料产品map
        Map<Integer, JSONObject> materielProductSortMap = new TreeMap<>();
        BusinessProductListVO businessProductListVO = new BusinessProductListVO();
        // 与productList同级，返回对应关联产品的attr
        String attrStr = "";
        String materielAttrStr = "";
        List<FieldAttrEntityExt> materielExplain = new ArrayList<>();
        List<FieldAttrEntityExt> finishProductExplain = new ArrayList<>();

        if (Objects.equals(sourceBusinessType, XbbRefTypeEnum.PRODUCTION_ORDER.getCode())) {
            materielExplain = explainHelp.getSelectProductExplains(XbbRefTypeEnum.BOM_BILL, corpid, BomBillEnum.MATERIEL.getAttr());
            finishProductExplain = explainHelp.getSelectProductExplains(XbbRefTypeEnum.BOM_BILL, corpid, BomBillEnum.PRODUCT.getAttr());
            // 生产单选择bom单产品
            for (BomProductEntity bomProductEntity : bomProductList) {
                Long productId = bomProductEntity.getProductId();
                PaasFormDataEntityExt productEntity = productMap.get(productId);

                ProductionOrderProductEntityExt productionOrderProduct = new ProductionOrderProductEntityExt();
                productionOrderProduct.setParentId(bomProductEntity.getParentId());
                productionOrderProduct.setProductId(productId);
                productionOrderProduct.setProductName(bomProductEntity.getProductName());
                productionOrderProduct.setProductNo(bomProductEntity.getProductNo());
                productionOrderProduct.setBarcode(bomProductEntity.getBarcode());
                productionOrderProduct.setProductSpecification(bomProductEntity.getProductSpecification());
                productionOrderProduct.setProductUnit(bomProductEntity.getProductUnit());
                productionOrderProduct.setProductUnitNum(bomProductEntity.getProductNum());
                productionOrderProduct.setProductNum(bomProductEntity.getProductNum());
                productionOrderProduct.setAttritionRate(bomProductEntity.getAttritionRate());
                if (bomProductEntity.getType() == 2) {
                    // 设置损耗率
                    Double attritionRate = bomProductEntity.getAttritionRate();
                    productionOrderProduct.setAttritionRate(attritionRate);
                    productionOrderProduct.setProductNum(Arith.div(Arith.mul(productionOrderProduct.getProductUnitNum(), fProductNum), Arith.div(Arith.sub(100, attritionRate), 100)));
                } else {
                    // 成品默认先给1，如果是待生产则给前端传入的数值，物料产品根据损耗率和单位生产数量计算
                    productionOrderProduct.setProductNum(fProductNum);
                }

                productionOrderProduct.setWarehouseId(0L);
                productionOrderProduct.setType(bomProductEntity.getType());
                // 没有仓库信息
                productionOrderProduct.setWarehouseObj(new JSONObject());
                // 库存是仓库的总库存
                ProductEntityExt productEntityExt = productMap.get(productId);
                if (productEntityExt != null) {
                    JSONObject productDataList = productEntityExt.getData();
                    productionOrderProduct.setStock(productDataList.getDouble(ProductEnum.STOCK.getAttr()));
                }
                productionOrderProduct.setSort(bomProductEntity.getSort() == null ? 0 : bomProductEntity.getSort());

                // 封面图
                if(productEntity != null) {
                    JSONArray imagesArray = productEntity.getData().getJSONArray(ProductEnum.PRODUCT_IMGS.getAttr());
                    productionOrderProduct.setImageUrlArray(imagesArray);
                }

                // 构建格式化生产单的DTO
                FormatProductionOrderProductDTO formatProductionOrderProductDTO = new FormatProductionOrderProductDTO();
                BeanUtil.copyProperties(businessProductListDTO, formatProductionOrderProductDTO);
                formatProductionOrderProductDTO.setUserEntity(userEntity);
                formatProductionOrderProductDTO.setProductionOrderProductEntityExt(productionOrderProduct);
                formatProductionOrderProductDTO.setNowProductExplainMap(nowProductExplainMap);
                formatProductionOrderProductDTO.setTargetCode(XbbRefTypeEnum.PRODUCTION_ORDER.getCode());
                JSONObject productObj = productionOrderService.getFormatProductJsonArray(formatProductionOrderProductDTO);
                if (Objects.equals(productionOrderProduct.getType(), 2)) {
                    materielAttrStr = ProductionOrderEnum.MATERIEL.getAttr();
                    materielProductSortMap.put(productionOrderProduct.getSort(), productObj);
                } else {
                    attrStr = ProductionOrderEnum.PRODUCT.getAttr();
                    productArray.add(productObj);
                }
            }
        } else if (Objects.equals(sourceBusinessType, XbbRefTypeEnum.SIMULATED_PRODUCTION.getCode())) {
            ProductExplainDTO productExplainDTO = new ProductExplainDTO();
            BeanUtil.copyProperties(businessProductListDTO, productExplainDTO);
            productExplainDTO.setXbbRefTypeEnum(XbbRefTypeEnum.BOM_BILL);
            productExplainDTO.setTargetCode(XbbRefTypeEnum.SIMULATED_PRODUCTION.getCode());
            productExplainDTO.setAttr(BomBillEnum.MATERIEL.getAttr());
            materielExplain = explainHelp.getSelectProductExplains(productExplainDTO);
            ProductFieldPojo productFieldPojo = saasFormHelp.getProductFieldPojo(RedisPrefixConstant.PRODUCT_UNIT, ProductEnum.UNIT.getAttr(), corpid);
            List<UnitItemPoJo> multiItemDataPoJoList = productFieldPojo.getMultiItemDataPoJoList();
            Map<Long, String> multiUnitMap = new HashMap();
            for (UnitItemPoJo itemPoJo : multiItemDataPoJoList) {
                multiUnitMap.put(itemPoJo.getValue(), itemPoJo.getText());
            }
            List<MultiUnitItemPoJo> multiItems = productFieldPojo.getMultiItems();
            Map<Long, MultiUnitItemPoJo> groupMap = multiItems.stream().collect(Collectors.toMap(MultiUnitItemPoJo::getValue, item -> item, (a, b) -> b, () -> new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY)));
            // 模拟生产选择bom单产品
            for (BomProductEntity bomProductEntity : bomProductList) {
                Long productId = bomProductEntity.getProductId();
                PaasFormDataEntityExt productEntity = productMap.get(productId);
                boolean enableMultiUnit = Objects.equals(productEntity.getData().getInteger(ProductEnum.ENABLE_MULTI_UNIT.getAttr()), 1);

                if (Objects.equals(bomProductEntity.getType(), 2)) {
                    // 物料
                    ProductionOrderProductEntityExt productionOrderProduct = new ProductionOrderProductEntityExt();
                    productionOrderProduct.setParentId(bomProductEntity.getParentId());
                    productionOrderProduct.setProductId(productId);
                    productionOrderProduct.setProductName(bomProductEntity.getProductName());
                    productionOrderProduct.setProductNo(bomProductEntity.getProductNo());
                    productionOrderProduct.setProductSpecification(bomProductEntity.getProductSpecification());
                    productionOrderProduct.setProductUnit(bomProductEntity.getProductUnit());
                    if (enableMultiUnit) {
                        productionOrderProduct.setProductUnit(multiUnitMap.getOrDefault(Long.valueOf(productionOrderProduct.getProductUnit()), ""));
                    }
                    productionOrderProduct.setProductUnitNum(bomProductEntity.getProductNum());
                    productionOrderProduct.setType(bomProductEntity.getType());
                    productionOrderProduct.setSort(bomProductEntity.getSort());
                    // 没有仓库信息
                    productionOrderProduct.setWarehouseObj(null);
                    // 设置损耗率
                    Double attritionRate = bomProductEntity.getAttritionRate();
                    productionOrderProduct.setAttritionRate(attritionRate);
                    try {
                        productionOrderProduct.setProductNum(Arith.div(productionOrderProduct.getProductUnitNum(), Arith.div(Arith.sub(100, attritionRate), 100)));
                    } catch (Exception arithmeticException) {
                        productionOrderProduct.setProductNum(1D);
                    }

                    // 封面图
                    if(productEntity != null) {
                        JSONArray imagesArray = productEntity.getData().getJSONArray(ProductEnum.PRODUCT_IMGS.getAttr());
                        productionOrderProduct.setImageUrlArray(imagesArray);
                    }

                    // 构建格式化生产单的DTO
                    FormatProductionOrderProductDTO formatProductionOrderProductDTO = new FormatProductionOrderProductDTO();
                    BeanUtil.copyProperties(businessProductListDTO, formatProductionOrderProductDTO);
                    formatProductionOrderProductDTO.setUserEntity(userEntity);
                    formatProductionOrderProductDTO.setProductionOrderProductEntityExt(productionOrderProduct);
                    formatProductionOrderProductDTO.setNowProductExplainMap(nowProductExplainMap);
                    formatProductionOrderProductDTO.setTargetCode(XbbRefTypeEnum.SIMULATED_PRODUCTION.getCode());
                    JSONObject productObj = productionOrderService.getFormatProductJsonArray(formatProductionOrderProductDTO);
                    JSONArray formatList = productObj.getJSONArray(StringConstant.RESULT);
                    if (enableMultiUnit) {
                        List<UnitItemPoJo> itemDataPoJoList = groupMap.get(productEntity.getData().getLong(ProductEnum.UNIT.getAttr())).getItemDataPoJoList();
                        productObj.put(ProductConstant.TRANSFORM_UNIT_RATE, itemDataPoJoList);
                    }
                    // 模拟生产产品去掉条码和单位数量、领料数量的字段
                    for (int i = formatList.size() - 1; i >= 0; i--) {
                        JSONObject jsonObject = formatList.getJSONObject(i);
                        String attr = jsonObject.getString(StringConstant.REDUNDANT_FIELD_ATTR_BEGIN_FLAG);
                        if (Objects.equals(attr, "num") || Objects.equals(attr, ProductEnum.BARCODE.getSaasAttr())) {
                            formatList.remove(jsonObject);
                        }
//                    if (Objects.equals(attr, "unitNum")) {
//                        jsonObject.put("decimalPrecision", numberPrecision);
//                    }
                        // 开始没有选仓库时物料库存显示为"- -"
                        if (Objects.equals(attr, ProductEnum.STOCK.getSaasAttr())) {
                            jsonObject.put("attrValue", "");
                        }
                    }
                    materielAttrStr = ProductionOrderEnum.MATERIEL.getAttr();
                    materielProductSortMap.put(productionOrderProduct.getSort(), productObj);
                } else {
                    // 成品
                    ProductEntityExt productEntityExt = productMap.get(productId);
                    JSONObject productData = productEntityExt.getData();
                    JSONObject finishProductObj = new JSONObject();
                    finishProductObj.put("id", productId);
                    finishProductObj.put("parentId", bomProductEntity.getParentId());
                    finishProductObj.put("productName", FastJsonHelper.getStringOrDefaultFromFormData(productData, ProductEnum.NAME.getAttr(), ""));
                    finishProductObj.put("productNo", bomProductEntity.getProductNo());
                    String specification = FastJsonHelper.getStringOrDefaultFromFormData(productData, ProductEnum.SPECIFICATION_LINK_TEXT.getAttr(), "");
                    if (Objects.equals(getIntegerOrDefaultFromFormData(productData, ProductEnum.SPECIFICATION.getAttr(), 0), 0)) {
                        finishProductObj.put("specification", specification);
                    } else {
                        finishProductObj.put("specification", specificationModel.joinSpecification(specification));
                    }
                    finishProductObj.put("stock", getDoubleOrDefaultFromFormData(productData, ProductEnum.STOCK.getAttr(), 0.0));
                    JSONArray defaultJSONArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(productData, ProductEnum.PRODUCT_IMGS.getAttr(), new JSONArray());
                    finishProductObj.put("thumbnail", FastJsonHelper.getJsonArrOrDefaultFromFormData(productData, ProductEnum.PRODUCT_IMGS.getAttr(), defaultJSONArray));
                    if (enableMultiUnit) {
                        List<UnitItemPoJo> itemDataPoJoList = groupMap.get(productData.getLong(ProductEnum.UNIT.getAttr())).getItemDataPoJoList();
                        finishProductObj.put(ProductConstant.TRANSFORM_UNIT_RATE, itemDataPoJoList);
                    }
                    attrStr = BomBillEnum.PRODUCT.getAttr();
                    productArray.add(finishProductObj);
                }
            }
        } else {
            materielExplain = explainHelp.getSelectProductExplains(XbbRefTypeEnum.BOM_BILL, corpid, BomBillEnum.MATERIEL.getAttr());
            finishProductExplain = explainHelp.getSelectProductExplains(XbbRefTypeEnum.BOM_BILL, corpid, BomBillEnum.PRODUCT.getAttr());
            // 普通选择BOM单产品
            for (BomProductEntity bomProductEntity : bomProductList) {
                FormatBomProductDTO formatBomProductDTO = new FormatBomProductDTO();
                formatBomProductDTO.setBomProductEntity(bomProductEntity);
                formatBomProductDTO.setNowProductExplainMap(nowProductExplainMap);
                JSONObject productObj = getFormatProductJsonArray(formatBomProductDTO, productMap);
                if (Objects.equals(bomProductEntity.getType(), 2)) {
                    materielAttrStr = BomBillEnum.MATERIEL.getAttr();
                    materielProductSortMap.put(bomProductEntity.getSort(), productObj);
                } else {
                    attrStr = BomBillEnum.PRODUCT.getAttr();
                    productArray.add(productObj);
                }
            }
        }

        // 产品排序
        materielProductArray.addAll(materielProductSortMap.values());
        // 物料产品
        materielProductFinalObj.put(StringConstant.PRODUCT_LIST, materielProductArray);
        materielProductFinalObj.put(StringConstant.REDUNDANT_FIELD_ATTR_BEGIN_FLAG, materielAttrStr);
        materielProductFinalObj.put(BusinessConstant.EXPLAINS, materielExplain);
        businessProductListVO.setMateriel(materielProductFinalObj);

        // 成品产品
        productFinalObj.put(StringConstant.PRODUCT_LIST, productArray);
        productFinalObj.put(StringConstant.REDUNDANT_FIELD_ATTR_BEGIN_FLAG, attrStr);
        productFinalObj.put(BusinessConstant.EXPLAINS, finishProductExplain);
        businessProductListVO.setFinishedProduct(productFinalObj);
        businessProductListVO.setPageHelper(pageHelper);
        return businessProductListVO;
    }






    /**
     * bom版本和产品关联校验：如果该成品没有默认版本的bom单，如果有，则将该成品关联的其他bom单的默认设置取消
     * @param corpid 公司id
     * @param productId 成品id
     * @author long.rao
     * @date 2019-02-21 10:34
     */
    private void checkBomAndFinshedProduct(String corpid, Long productId,Long bomId) throws XbbException{
        List<PaasFormDataEntityExt> bomEntityExtList = new ArrayList<>();
        // 获取成品关联的默认版本的bom单
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
        boolQueryBuilder.filter(termQuery("data." + BomBillEnum.PRODUCT.getAttr(), productId));
        boolQueryBuilder.filter(termQuery("data." + BomBillEnum.VERSION_LINK_TEXT.getAttr(), 1));
        boolQueryBuilder.mustNot(termQuery(FieldTypeEnum.DATAID.getAlias(), bomId));
        boolQueryBuilder.filter(termQuery("del", 0));
        List<String> fieldList = new ArrayList<>();
        fieldList.add("data." + BomBillEnum.VERSION_LINK_TEXT.getAttr());
        fieldList.add((StringConstant.DATA_ID));
        bomEntityExtList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_BOM,boolQueryBuilder,PaasFormDataEntityExt.class, fieldList);


        if (bomEntityExtList != null && !bomEntityExtList.isEmpty()) {
            // 该成品有默认的bom单
            // 将此版本设为默认，则将该成品关联的其他bom单的默认设置取消
            List<Long> bomIds = new ArrayList<>(bomEntityExtList.size());
            for (PaasFormDataEntityExt entity : bomEntityExtList) {
                JSONObject data = entity.getData();
                Integer defaultVersion = getIntegerFromFormData(data, BomBillEnum.VERSION_LINK_TEXT.getAttr());
                if (defaultVersion != null && defaultVersion == 1) {
                    bomIds.add(entity.getDataId());
                }
            }
            proUpdateHelp.updateByIds(XbbRefTypeEnum.BOM_BILL.getCode(), corpid, bomIds, BomBillEnum.VERSION_LINK_TEXT.getAttr(), 0);
        }
    }

    /**
     * 新建时，把当前用户做为负责人
     *
     * @param bomId      bomId
     * @param userEntity 当前用户的实体
     * @author long.rao
     * @date 2019-02-17 16:45
     */
    private void saveBomBillUser(Long bomId, UserEntity userEntity) throws XbbException {
        long now = DateUtil.getInt();
        BomUserEntity bomUserEntity = new BomUserEntity();
        bomUserEntity.setCorpid(userEntity.getCorpid());
        bomUserEntity.setUserId(userEntity.getUserId());
        bomUserEntity.setUserName(userEntity.getName());
        bomUserEntity.setUserAvatar(userEntity.getAvatar());
        bomUserEntity.setDataId(bomId);
        bomUserEntity.setIsMain(1);
        bomUserEntity.setAddTime(now);
        bomUserEntity.setUpdateTime(now);
        bomUserModel.save(bomUserEntity);
    }

    /**
     * bom版本查重
     *
     * @param finishedProductVersion bom版本名称
     * @param bomId                  bom清单id
     * @param productId              bom清单成品产品id
     * @author feng.zheng
     * @date 2019/2/19 21:41
     */
    @Override
    public FormDataRepeatVO checkRepeatForBomVersion(RepeatCommonConditionDTO repeatCommonConditionDTO, String finishedProductVersion, Long bomId, Long productId,Boolean isSave) throws XbbException {
        // bom清单成品id
        FormDataRepeatDTO formDataRepeatDTO = new FormDataRepeatDTO();
        BeanUtil.copyProperties(repeatCommonConditionDTO, formDataRepeatDTO);
        formDataRepeatDTO.setAttr(BomBillEnum.PRODUCT.getAttr());
        formDataRepeatDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
        formDataRepeatDTO.setValue(productId);
        // 拼接条件，版本
        ConditionsEntityExt conditionsEntityExt = new ConditionsEntityExt();
        conditionsEntityExt.setAttr(BomBillEnum.VERSION.getAttr());
        //判断是保存BOM清单时查重还是输入时查重
        if (isSave) {
            conditionsEntityExt.setSymbol(ConditionEnum.EQUAL.getSymbol());
        }else {
            conditionsEntityExt.setSymbol(ConditionEnum.LIKE.getSymbol());
        }
        conditionsEntityExt.setValue(Collections.singletonList(finishedProductVersion));
        conditionsEntityExt.setFieldType(FieldTypeEnum.TEXT.getType());
        return saasSaveHelp.isUniqueByConditions(formDataRepeatDTO, Arrays.asList(conditionsEntityExt));
    }


    /**
     * 根据产品判断是否有可用的bom单（启用， 不在审批中）
     * @param productId 产品id
     * @param corpid    公司id
     * @return
     */
    @Override
    public boolean hasEnabledBom(Long productId, String corpid) throws XbbException{
        List<PaasFormDataEntityExt> bomEntityExtList = new ArrayList<>();
            // 获取成品关联的默认版本的bom单
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
        boolQueryBuilder.filter(termQuery("data." + BomBillEnum.STATUS.getAttr(), 1));
        boolQueryBuilder.filter(termsQuery("data." + BomBillEnum.PRODUCT.getAttr(), Collections.singleton(productId)));
        boolQueryBuilder.filter(termQuery("del", 0));
        boolQueryBuilder.filter(termsQuery("flowStatus", Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType())));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_BOM.getType()));
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(boolQueryBuilder);
        SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_BOM.getIndex());
        searchRequest.source(sourceBuilder);
        Long count = xbbElasticsearchRestTemplate.count(searchRequest, PaasFormDataEntityExt.class);

        if (count !=null && count > 0L) {
            return true;
        }
        return false;
    }

    @Override
    public BomDeleteBatchVO deleteBatch(BomDeleteBatchDTO bomDeleteBatchDTO) throws XbbException {
        BomDeleteBatchVO bomDeleteBatchVO = new BomDeleteBatchVO();
        try {
            // TODO 权限校验
            // TODO 老板、超管、负责人有删除BOM单的权限
            List<Long> bomIdIn = bomDeleteBatchDTO.getDataIdList();
            String corpid = bomDeleteBatchDTO.getCorpid();

            //查询产品名称
            Map<String, String> bomBillNoAndName= new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            BoolQueryBuilder productBuilder = boolQuery();
            // 添加corpid,formId,del
            productBuilder.filter(termQuery("corpid.keyword", corpid));
            productBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
            productBuilder.filter(termsQuery(StringConstant.DATA_ID, bomIdIn));
            List<String> fieldList = new ArrayList<>();
            fieldList.add(FieldTypeEnum.SERIALNO.getAlias());
            fieldList.add("data." + BomBillEnum.NAME.getAttr());
            fieldList.add("data." + BomBillEnum.PRODUCT.getAttr());
            List<PaasFormDataEntityExt> bomBillList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_BOM, productBuilder, PaasFormDataEntityExt.class, fieldList);
            for(PaasFormDataEntityExt bomBill : bomBillList){
                JSONObject data = bomBill.getData();
                String bomNo = bomBill.getSerialNo();
                String bomName = FastJsonHelper.getStringOrDefaultFromFormData(data, BomBillEnum.NAME.getAttr(), "");
                bomBillNoAndName.put(bomNo, bomName);
            }
            if(!bomIdIn.isEmpty()) {
                if(BasicConstant.ONE.equals(bomDeleteBatchDTO.getSingleFlag())
                        && BasicConstant.ONE.equals(bomIdIn.size())){
                    bomBillModel.deleteByKey(bomIdIn.get(0),corpid);
                }else {
                    bomBillModel.deleteBatch(bomIdIn, corpid);
                }
                bomDeleteBatchVO.setDeleteIds(bomIdIn);
            }
            // 删除关联产品
            BomProductDeleteBatchDTO bomProductDeleteBatchDTO = new BomProductDeleteBatchDTO();
            BeanUtil.copyProperties(bomDeleteBatchDTO, bomProductDeleteBatchDTO);
            bomProductDeleteBatchDTO.setBomIdIn(bomIdIn);
            bomProductService.deleteBatch(bomProductDeleteBatchDTO);
            // 删除关联负责人
            BomUserDeleteBatchDTO bomUserDeleteBatchDTO = new BomUserDeleteBatchDTO();
            BeanUtil.copyProperties(bomDeleteBatchDTO, bomUserDeleteBatchDTO);
            bomUserDeleteBatchDTO.setBomIdIn(bomIdIn);
            bomUserService.deleteBatch(bomUserDeleteBatchDTO);
            // 将相相关联产品待生产改为待采购
            // bom清单关联产品ID
            List<Long> bomProductIdList = new ArrayList<>();
            // 根据ID去BOM表将关联产品ID数据查出
            bomBillList.stream().map(PaasFormDataEntityExt::getData)
                    .filter(data -> data.containsKey(BomBillEnum.PRODUCT.getAttr()))
                    .forEach(data -> bomProductIdList.addAll(data.getJSONArray(BomBillEnum.PRODUCT.getAttr()).toJavaList(Long.class)));
            // 回退智能补货数量
            // 如果产品从待采购变为待生产 则需要先从数据库中查询出这些产品的所有数量
            // 当前待采购的有多少 就有多少是需要变更为待生产的  智能补货需要减去这一部分
            Map<String, Object> contParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            contParam.put(ParameterConstant.CORPID, corpid);
            contParam.put("productIdIn", bomProductIdList);
            contParam.put("del", 0);
            // 是待生产的才计入
            contParam.put("isProduce", ContractProduceEnum.WAIT_PRODUCE.getCode());
            List<ContractProductEntity> contractProductList = contractProductModel.findEntitys(contParam);
            if (CollectionUtils.isNotEmpty(contractProductList)){
                Map<Long,Double> productNumMap = new HashMap<>();
                Map<Long,Double> outNumMap = new HashMap<>();
                // 看看变更前是否是待生产的 如果是了就不更新了 如果不是再更新
                for (ContractProductEntity contractProductEntity : contractProductList) {
                    Long productId = contractProductEntity.getProductId();
                    Double productNum = contractProductEntity.getProductNum();
                    Double outstockNum = contractProductEntity.getOutstockNum();
                    if (productNumMap.containsKey(productId)){
                        productNumMap.put(productId,Arith.add(productNumMap.get(productId),productNum));
                    }else {
                        productNumMap.put(productId,productNum);
                    }
                    if (outNumMap.containsKey(productId)){
                        outNumMap.put(productId,Arith.add(outNumMap.get(productId),outstockNum));
                    }else {
                        outNumMap.put(productId,outstockNum);
                    }
                }
                // 封装未出库数量
                Map<Long,Double> waitOutNumMap = new HashMap<>();
                for (Map.Entry<Long, Double> entry : productNumMap.entrySet()) {
                    Long productId = entry.getKey();
                    Double productNum = entry.getValue();
                    Double outNum = outNumMap.getOrDefault(productId, 0D);
                    waitOutNumMap.put(productId,Arith.sub(productNum,outNum));
                }

                List<SmartReplenishmentEntity> smartReplenishmentEntityList = smartReplenishmentModel.getByProductList(corpid, bomProductIdList);
                if (CollectionUtils.isNotEmpty(smartReplenishmentEntityList)){
                    for (SmartReplenishmentEntity smartReplenishmentEntity : smartReplenishmentEntityList) {
                        Double waitOutstockNum = smartReplenishmentEntity.getWaitOutstockNum();
                        Long productId = smartReplenishmentEntity.getProductId();
                        Double changeNum = waitOutNumMap.getOrDefault(productId, 0D);
                        smartReplenishmentEntity.setWaitOutstockNum(Arith.add(waitOutstockNum,changeNum));
                    }
                    smartReplenishmentModel.updateBatch(smartReplenishmentEntityList,corpid);
                }
            }

            contractProductModel.updateIsProduceByProductId(0, corpid, bomProductIdList);
            // TODO 删除关联的审批

            //生成删除日志(区分单个删除和批量删除)
            String userId = bomDeleteBatchDTO.getUserId();
            String userName = bomDeleteBatchDTO.getLoginUserName();
            List<String> list = new ArrayList<>();
            Iterator<String> iterator = bomBillNoAndName.keySet().iterator();
            while (iterator.hasNext()) {
                String key = iterator.next();
                String value = bomBillNoAndName.get(key);
                if(StringUtil.isEmpty(value)){
                    list.add(key);
                } else {
                    StringBuilder sb = new StringBuilder();
                    sb.append(key).append("（").append(value).append("）");
                    list.add(sb.toString());
                }
            }
            OperateTypeEnum operateTypeEnum = OperateTypeEnum.DELETE;
            if (Objects.equals(1, bomDeleteBatchDTO.getIsBusinessRule())) {
                operateTypeEnum = OperateTypeEnum.RULE_DELETE;
            }
            String nameStr = StringUtils.join(list, "，");
            if(bomIdIn.size() > 1){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_DELETE_FORM_DETAIL), userName, XbbRefTypeEnum.BOM_BILL.getName(), bomIdIn.size());
                List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                InfoArrPojo infoArrPojo = new InfoArrPojo();
                infoArrPojo.setTitle(BomBillEnum.SHEET_NO.getAttrName());
                infoArrPojo.setContent(nameStr);
                infoArrPojoList.add(infoArrPojo);
                mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.BOMBILL, operateTypeEnum,
                        "", "", memo, bomDeleteBatchDTO.getHttpHeader());
            } else if (Objects.equals(bomIdIn.size(), 1)){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DELETE_WORK), userName, XbbRefTypeEnum.BOM_BILL.getName(), nameStr);
                mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.BOMBILL, operateTypeEnum,
                        bomIdIn.get(0).toString(), nameStr, memo, bomDeleteBatchDTO.getHttpHeader());
            }
        } catch (Exception e) {
            LOG.error("bomBillServiceImpl.deleteBatch 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return bomDeleteBatchVO;
    }

    @Override
    public void batchEditAttr(BomEditAttrUpdateDTO bomEditAttrUpdateDTO) throws XbbException {
        try {
            List<BomUpdateDTO> bomList = new ArrayList<>();
            bomEditAttrUpdateDTO.getDataIdList().forEach((item)->{
                BomUpdateDTO payment = new BomUpdateDTO();
                payment.setId(item);
                JSONObject data = ProSaveHelp.getBatchUpdateData(bomEditAttrUpdateDTO.getFieldEditedList());
                payment.setData(data);
                bomList.add(payment);
            });
            List<BomBillEntityExt> bomBillEntityList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            if (!bomList.isEmpty()) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", bomEditAttrUpdateDTO.getCorpid());
                param.put("idIn", bomEditAttrUpdateDTO.getDataIdList());
                bomBillEntityList = bomBillModel.findEntitys(param);
                if (Objects.isNull(bomBillEntityList)){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
                }
                //权限团队校验前置了
                List<Long> errorIdList = new ArrayList<>();
//                List<Long> errorIdList = userTeamHelp.batchTeamMembersCheckEditPermission(bomEditAttrUpdateDTO.getBusinessType(), bomEditAttrUpdateDTO.getSaasMark(),
//                        bomEditAttrUpdateDTO.getMenuId(), bomEditAttrUpdateDTO.getLoginUser(), bomEditAttrUpdateDTO.getDistributorMark(),
//                        bomEditAttrUpdateDTO.getDataIdList(), new HashMap<>());
                List<String> errorNameList = new ArrayList<>();
                for (BomBillEntityExt bomBillEntityExt : bomBillEntityList) {
                    if (errorIdList.contains(bomBillEntityExt.getId())) {
                        errorNameList.add(bomBillEntityExt.getData().getString(BomBillEnum.NAME.getAttr()));
                    }
                }
                String nameStr = org.apache.commons.lang.StringUtils.join(errorNameList, "、");
                if (CollectionUtils.isNotEmpty(errorNameList)) {
                    throw new XbbException(UserTeamErrorCodeEnum.API_ERROR_271038.getCode(), String.format(UserTeamErrorCodeEnum.API_ERROR_271038.getMsg(), nameStr));
                }
                BomUpdateBatchDTO bomUpdateBatchDTO = new BomUpdateBatchDTO();
                BeanUtil.copyProperties(bomEditAttrUpdateDTO, bomUpdateBatchDTO);
                bomUpdateBatchDTO.setBomList(bomList);
                updateBatch(bomUpdateBatchDTO);
            }
            Boolean isFieldDependence = bomEditAttrUpdateDTO.getIsFieldDependence();
            // 更新的字段
            AttrValuePojo singleAttrValuePojo = ProSaveHelp.getSingleAttrValuePojo(isFieldDependence, bomEditAttrUpdateDTO.getFieldEditedList());
            // 如果更新的字段等于BOM状态则进行以下if代码
            if (StringUtils.isNotBlank(singleAttrValuePojo.getAttr()) && StringUtils.equals(BomBillEnum.STATUS.getAttr(), singleAttrValuePojo.getAttr()) && CollectionUtils.isNotEmpty(bomBillEntityList)) {
                // 公司ID
                String corpid = bomEditAttrUpdateDTO.getCorpid();
                // bom清单关联产品ID
                List<Long> bomProductIdList = new ArrayList<>();
                // 将成品产品ID取出
                bomBillEntityList.stream().map(BomBillEntityExt::getData)
                        .filter(data -> data.containsKey(BomBillEnum.PRODUCT.getAttr()))
                        .forEach(data -> bomProductIdList.addAll(data.getJSONArray(BomBillEnum.PRODUCT.getAttr()).toJavaList(Long.class)));
                // 获取[新建合同订单缺货时自动更新]表单配置
                Map<String, Object> formConfigParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                formConfigParam.put(ParameterConstant.CORPID, corpid);
                formConfigParam.put("config", FormConfigEnum.PRODUCTION_ORDER_AUTO_UPDATE_NEW_CONTRACT.getConfig());
                List<FormConfigEntity> formConfigList = formConfigModel.findEntitys(formConfigParam);
                // 更新合同表数据
                if(CollectionUtils.isNotEmpty(formConfigList) && CollectionUtils.isNotEmpty(bomProductIdList)){
                    // 代表该合同产品是显示在待生产列表还是待采购列表，1：待生产列表；0：待采购列表，默认0
                    // bom禁用是状态标记为0
                    int isProduce = "0".equals(singleAttrValuePojo.getAttr()) ? 0 : 1;
                    // 同一个公司同一个配置选择应当只有一个
                    FormConfigEntity formConfigEntity = formConfigList.get(0);
                    // 只有勾选了才进这段才会进生产单,没勾选不管bom启用还是禁用都去待采购列表
                    if(StringUtils.equals(formConfigEntity.getConfigValue(), "0")){
                        isProduce = 0;
                    }
                    // 更新智能补货数量 必须在更新合同产品之前执行
                    Map<String, Object> contParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    contParam.put(ParameterConstant.CORPID, corpid);
                    contParam.put("productIdIn", bomProductIdList);
                    contParam.put("del", 0);
                    if (Objects.equals(isProduce,1)){
                        // 如果产品从待采购变为待生产 则需要先从数据库中查询出这些产品的所有数量
                        // 当前待采购的有多少 就有多少是需要变更为待生产的  智能补货需要减去这一部分
                        // 是待采购的才计入
                        contParam.put("isProduce", ContractProduceEnum.WAIT_PURCHASE.getCode());
                    }else {
                        // 如果产品从待生产变为待采购 则需要先从数据库中查询出这些产品的所有数量
                        // 当前待生产的有多少 就有多少是需要变更为待采购的  智能补货需要减去这一部分
                        // 是待生产的才计入
                        contParam.put("isProduce", ContractProduceEnum.WAIT_PRODUCE.getCode());
                    }
                    List<ContractProductEntity> contractProductList = contractProductModel.findEntitys(contParam);
                    if (CollectionUtils.isNotEmpty(contractProductList)){
                        // 产品数量map
                        Map<Long,Double> productNumMap = new HashMap<>();
                        // 出库数量map
                        Map<Long,Double> outNumMap = new HashMap<>();
                        for (ContractProductEntity contractProductEntity : contractProductList) {
                            Long productId = contractProductEntity.getProductId();
                            Double productNum = contractProductEntity.getProductNum();
                            Double outstockNum = contractProductEntity.getOutstockNum();
                            if (productNumMap.containsKey(productId)){
                                productNumMap.put(productId,Arith.add(productNumMap.get(productId),productNum));
                            }else {
                                productNumMap.put(productId,productNum);
                            }
                            if (outNumMap.containsKey(productId)){
                                outNumMap.put(productId,Arith.add(outNumMap.get(productId),outstockNum));
                            }else {
                                outNumMap.put(productId,outstockNum);
                            }
                        }
                        // 未出库数量map
                        Map<Long,Double> waitOutNumMap = new HashMap<>();
                        // 处理未出库数量
                        for (Map.Entry<Long, Double> entry : productNumMap.entrySet()) {
                            Long productId = entry.getKey();
                            Double productNum = entry.getValue();
                            Double outNum = outNumMap.getOrDefault(productId, 0D);
                            waitOutNumMap.put(productId,Arith.sub(productNum,outNum));

                        }
                        List<SmartReplenishmentEntity> smartReplenishmentEntityList = smartReplenishmentModel.getByProductList(corpid, bomProductIdList);
                        if (CollectionUtils.isNotEmpty(smartReplenishmentEntityList)){
                            for (SmartReplenishmentEntity smartReplenishmentEntity : smartReplenishmentEntityList) {
                                Double waitOutstockNum = smartReplenishmentEntity.getWaitOutstockNum();
                                Long productId = smartReplenishmentEntity.getProductId();
                                Double changeNum = waitOutNumMap.getOrDefault(productId, 0D);
                                if (Objects.equals(isProduce,1)){
                                    smartReplenishmentEntity.setWaitOutstockNum(Arith.sub(waitOutstockNum,changeNum));
                                }else {
                                    smartReplenishmentEntity.setWaitOutstockNum(Arith.add(waitOutstockNum,changeNum));
                                }
                            }
                            smartReplenishmentModel.updateBatch(smartReplenishmentEntityList,corpid);
                        }
                    }
                    contractProductModel.updateIsProduceByProductId(isProduce, corpid, bomProductIdList);
                }
            }


            // 批量编辑日志
            List<String> updataItemList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<Long> dataIdList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (BomBillEntityExt item : bomBillEntityList) {
                dataIdList.add(item.getId());
                JSONObject data = item.getData();
                String serialNo = item.getSerialNo();
                String opObjectName = data.getString(BomBillEnum.NAME.getAttr());
                StringBuilder sb = new StringBuilder();
                opObjectName = opObjectName == null ? serialNo : sb.append(serialNo).append("（").append(opObjectName).append("）").toString();
                updataItemList.add(opObjectName);
            }
            String updataItem = StringUtils.join(updataItemList, "，");
            String userId = bomEditAttrUpdateDTO.getUserId();
            String corpid = bomEditAttrUpdateDTO.getCorpid();
            String loginUserName = bomEditAttrUpdateDTO.getLoginUserName();
            // 标签特殊处理
            Integer fieldType = bomEditAttrUpdateDTO.getFieldType();
            logHelp.analysisLabel(corpid, fieldType, isFieldDependence,bomEditAttrUpdateDTO.getLogFieldEditedList());

            String changedLogItemsStr = logHandleHelp.getChangedLogItemsStr(bomEditAttrUpdateDTO.getLogFieldEditedList());
            if(dataIdList.size() > 1 ){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM_DATA_BATCH_ATTR), loginUserName, XbbRefTypeEnum.BOM_BILL.getName(),
                        changedLogItemsStr, dataIdList.size());
                List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                InfoArrPojo infoArrPojo = new InfoArrPojo();
                infoArrPojo.setTitle(XbbRefTypeEnum.BOM_BILL.getName());
                infoArrPojo.setContent(updataItem);
                infoArrPojoList.add(infoArrPojo);
                mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, loginUserName, OperateModuleTypeEnum.BOMBILL, OperateTypeEnum.EDIT,
                        "", "", memo, bomEditAttrUpdateDTO.getHttpHeader());
            } else if (Objects.equals(dataIdList.size(), 1)){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM_DATA_ATTR), loginUserName, XbbRefTypeEnum.BOM_BILL.getName(), updataItem,
                        changedLogItemsStr);
                mongoLogHelp.buildLog(corpid, userId, loginUserName, OperateModuleTypeEnum.BOMBILL, OperateTypeEnum.EDIT,
                        dataIdList.get(0).toString(), updataItem, memo, bomEditAttrUpdateDTO.getHttpHeader());
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("bomBillService.batchEditAttr 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }


    @Override
    public PaasFormDataEsListVO list(BomBillListDTO bomBillListDTO) throws XbbException {
        PaasFormEntity paasFormEntity = paasFormModel.getByBusinessType(XbbRefTypeEnum.BOM_BILL.getCode(),bomBillListDTO.getCorpid());
        BusinessDataDTO businessDataDTO = new BusinessDataDTO();
        BeanUtil.copyProperties(bomBillListDTO,businessDataDTO);
        businessDataDTO.setFormId(paasFormEntity.getId());
        businessDataDTO.setSourceBusinessType(XbbRefTypeEnum.PRODUCTION_ORDER.getCode());
        businessDataDTO.setCategoryId(bomBillListDTO.getCategoryId().toString());
        return paasFormDataService.getBusinessDataList(businessDataDTO);
//        BomBillListVO bomBillListVO = new BomBillListVO();
//        try {
//            String corpid = bomBillListDTO.getCorpid();
//            // 获取bom字段
//            Integer businessType = bomBillListDTO.getBusinessType();
//            PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByBusinessType(businessType, corpid);
//            if (Objects.isNull(paasFormExplainEntity)) {
//                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
//            }
//            List<FieldAttrEntity> explainList = JSONObject.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
//            Boolean nameEnable = paasFormExplainService.checkRequiredBySaasAttr(explainList, BomBillEnum.NAME.getSaasAttr());
//            List<FieldAttrEntity> head = getHead(nameEnable, explainList);
//
//            PaasFormEntityExt paasFormEntityExt = new PaasFormEntityExt();
//            paasFormEntityExt.setBusinessName(XbbRefTypeEnum.getByCode(businessType).getName());
//            String mainAttr = BomBillEnum.SHEET_NO.getAttr();
//            paasFormEntityExt.setMainAttr(mainAttr);
//
//            Long categoryId = bomBillListDTO.getCategoryId();
//            List<Long> categoryIdInList = new ArrayList<>();
//            ProductCategoryEntity productCategoryEntity = productCategoryModel.getByKey(categoryId, corpid);
//            if (Objects.nonNull(productCategoryEntity)) {
//                String routerLike = productCategoryEntity.getRouter();
//                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//                param.put("corpid", corpid);
//                param.put("del", 0);
//                param.put("routerLike", routerLike);
//                List<ProductCategoryEntity> categoryList = productCategoryModel.findEntitys(param);
//                for (ProductCategoryEntity entity : categoryList) {
//                    categoryIdInList.add(entity.getId());
//                }
//                if (categoryIdInList.isEmpty()) {
//                    categoryIdInList.add(-1L);
//                }
//            }
//
//            // 获取产品
//            List<PaasFormDataEntity> productList = getProductIdIn(corpid, categoryIdInList);
//            List<Object> productIdList = new ArrayList<>();
//            productList.forEach(item->{
//                if(Objects.nonNull(item.getDataId())) {
//                    productIdList.add(item.getDataId());
//                }
//            });
//            if (productIdList.isEmpty()){
//                productIdList.add(-1);
//            }
//            // 下属条件，默认看到自己和下属负责和协同的
//            UserVO userVO = bomBillListDTO.getLoginUser();
//            UserEntity userEntity = new UserEntity();
//            BeanUtil.copyProperties(userVO, userEntity);
//            List<String> userIdIn = userModel.getSubIdList(userEntity, 1);
//            userIdIn.add(bomBillListDTO.getUserId());
//            List<Object> bomIdInByUserId = getBomIdIn(corpid, userIdIn);
//            if (bomIdInByUserId.isEmpty()) {
//                bomBillListVO.setHeadList(head);
//                bomBillListVO.setPageHelper(new PageHelper());
//                bomBillListVO.setPaasFormDataESList(new ArrayList<>());
//                bomBillListVO.setForm(paasFormEntityExt);
//                return bomBillListVO;
//            }
//
//            // 开始检索bom数据
//            FormDataListDTO formDataListDTO = new FormDataListDTO();
//            BeanUtil.copyProperties(bomBillListDTO, formDataListDTO, false);
//            List<ConditionsEntityExt> conditionsList = new ArrayList<>();
//            ConditionsEntityExt conditionsEntityExt = new ConditionsEntityExt();
//            conditionsEntityExt.setValue(bomIdInByUserId);
//            conditionsEntityExt.setAttr(StringConstant.DATA_ID);
//            conditionsEntityExt.setFieldType(FieldTypeEnum.DATAID.getType());
//            conditionsEntityExt.setSymbol(ConditionEnum.IN.getSymbol());
//            conditionsList.add(conditionsEntityExt);
//            ConditionsEntityExt productCondition = new ConditionsEntityExt();
//            productCondition.setValue(productIdList);
//            productCondition.setAttr(BomBillEnum.PRODUCT.getAttr());
//            productCondition.setFieldType(BomBillEnum.PRODUCT.getFieldType());
//            productCondition.setSymbol(ConditionEnum.IN.getSymbol());
//            conditionsList.add(productCondition);
//            ConditionsEntityExt statusCondition = new ConditionsEntityExt();
//            statusCondition.setValue(Arrays.asList("1"));
//            statusCondition.setAttr(BomBillEnum.STATUS.getAttr());
//            statusCondition.setFieldType(BomBillEnum.STATUS.getFieldType());
//            statusCondition.setSymbol(ConditionEnum.EQUAL.getSymbol());
//            conditionsList.add(statusCondition);
//            formDataListDTO.setConditions(conditionsList);
//            PaasFormDataEsListVO paasFormDataEsListVO = paasFormDataEsModel.list(formDataListDTO);
//            if (Objects.isNull(paasFormDataEsListVO) || Objects.isNull(paasFormDataEsListVO.getPaasFormDataESList()) ) {
//                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
//            }
//            List<Long> bomIdIn = new ArrayList<>();
//            List<PaasFormDataEntityExt> bomList = paasFormDataEsListVO.getPaasFormDataESList();
//            bomList.forEach(item->{
//                bomIdIn.add(item.getDataId());
//            });
//            Map<String, Object> bomProductParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//            bomProductParam.put("corpid", corpid);
//            bomProductParam.put("bomIdIn", bomIdIn);
//            bomProductParam.put("productIdIn", productIdList);
//            bomProductParam.put("del", DelEnum.NORMAL.getDel());
//            bomProductParam.put("type", 1);
//            List<BomProductEntity> bomProductList = bomProductModel.findEntitys(bomProductParam);
//            // 一个bom单只对应一个成品,bomProductMap用于存放bomId与对应的成品实体
//            Map<Long, BomProductEntity> bomProductMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//            for (BomProductEntity item : bomProductList) {
//                bomProductMap.put(item.getBomId(), item);
//            }
//
////            BoolQueryBuilder boolQueryBuilder = boolQuery();
////            boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
////            boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(),productIdList));
////            boolQueryBuilder.filter(termQuery(StringConstant.DEL,DelEnum.NORMAL.getDel()));
////            List<PaasFormDataEntityExt> entitys = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_PRODUCT,boolQueryBuilder,PaasFormDataEntityExt.class,Arrays.asList(FieldTypeEnum.DATAID.getAlias(),ProductEnum.getAttrConnectData(ProductEnum.SPECIFICATION_LINK_TEXT)));
//            Map<Long, String> productMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//            for (PaasFormDataEntity item : productList) {
//                productMap.put(item.getDataId(), item.getData().getString(ProductEnum.SPECIFICATION_LINK_TEXT.getAttr()));
//            }
//
//            for (PaasFormDataEntityExt item : bomList) {
//                BomProductEntity bomProductEntity = bomProductMap.get(item.getId());
//                String productSpecification = productMap.get(bomProductEntity.getProductId());
//                if (bomProductEntity == null) {
//                    continue;
//                }
//                JSONObject data = item.getData();
//                if (Objects.nonNull(data)) {
//                    String value4Show = item.getSerialNo();
//                    String name = FastJsonHelper.getStringOrDefaultFromFormData(data, BomBillEnum.NAME.getAttr(), "");
//                    if (!nameEnable) {
//                        // 名称字段没有启用，则编号后面拼接名称，便于查看
//                        if (name != null && !name.isEmpty()) {
//                            value4Show += "(" + name + ")";
//                        }
//                    }
//                    data.put(BomBillEnum.SHEET_NO.getAttr(), value4Show);
//                    data.put(BomBillEnum.NAME.getAttr(), name);
//                    data.put(BomBillEnum.VERSION.getAttr(), data.getString(BomBillEnum.VERSION.getAttr()));
//                    data.put(BomBillEnum.PRODUCT_NAME.getAttr(), bomProductEntity.getProductName());
//                    data.put(BomBillEnum.PRODUCT_NO.getAttr(), bomProductEntity.getProductNo());
//                    data.put(BomBillEnum.PRODUCT_SPECIFICATION.getAttr(), specificationModel.joinSpecification(productSpecification));
//                }
//                item.setSourceData(data);
//            }
//
//            bomBillListVO.setHeadList(head);
//            bomBillListVO.setPageHelper(paasFormDataEsListVO.getPageHelper());
//            bomBillListVO.setPaasFormDataESList(bomList);
//            bomBillListVO.setForm(paasFormEntityExt);
//        } catch (XbbException e) {
//            throw e;
//        } catch (Exception e) {
//            LOG.error("bomBillService.list 执行出错：", e);
//            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
//        }
//        return bomBillListVO;
    }

    @Override
    public BaseVO changeStatus(ChangeStatusDTO changeStatusDTO) throws XbbException {
        // TODO BOM编辑权限校验
        Long dataId = changeStatusDTO.getDataId();
        Integer businessType = changeStatusDTO.getBusinessType();
        String corpid = changeStatusDTO.getCorpid();
        PaasFormDataEntityExt paasFormDataEntityExt = saasGetHelp.getFormData(dataId, corpid, businessType);
        if (paasFormDataEntityExt == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
        }
        JSONObject bomData = paasFormDataEntityExt.getData();
        String type = changeStatusDTO.getType();
        String oldType = FastJsonHelper.getStringOrDefaultFromFormData(bomData, BomBillEnum.STATUS.getAttr(), "");
        if (Objects.equals(oldType, type)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, ErrorMessageConstant.STATUS_NOT_MODIFIED);
        } else {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(BomBillEnum.STATUS.getAttr(), type);
            UpdateDataEntity updateData = ExplainUtil.getUpdateData(dataId, jsonObject, corpid);
            bomBillModel.updateBatch(Collections.singletonList(updateData), corpid);
            //  TODO 消息
        }
        return new BaseVO();
    }

    @Override
    public FormDataAddDTO formatExcelValue(ImportFormDataDTO importFormDataDTO, List<CellTitlePojo> titlePojoList, RowGroupPojo rowGroupPojo, List<FieldAttrEntityForImport> fieldAttrList) throws XbbException {
        FormDataAddDTO formDataAddDTO = new FormDataAddDTO();
        BeanUtil.copyProperties(importFormDataDTO, formDataAddDTO);
        JSONObject dataJson = new JSONObject();
        List<List<CellValuePojo>> rowValueList = rowGroupPojo.getRowValueList();
        // 分组的第一条数据作为给实体对象赋值的数据
        List<CellValuePojo> cellValueList = rowValueList.get(0);
        String corpid = importFormDataDTO.getCorpid();
        for (FieldAttrEntityForImport fieldAttr : fieldAttrList) {
            String attr = fieldAttr.getAttr();
            String attrName = fieldAttr.getAttrName();
            Integer fieldType = fieldAttr.getFieldType();
            Integer columnIndex = importHelper.getColumnIndexByTitle(titlePojoList, attrName, null);
            Object cellValue = importHelper.getValueByColumnIndex(cellValueList, columnIndex);

            if (Objects.equals(attr, BomBillEnum.PRODUCT.getAttr())) {
                // 成品产品只能填写一条数据
                List<List<CellValuePojo>> firstRowValueList = new ArrayList<>();
                firstRowValueList.add(cellValueList);
                importHelper.formatCommonProduct(titlePojoList, dataJson, firstRowValueList, fieldAttr, XbbRefTypeEnum.BOM_BILL.getCode(), corpid);
            } else if (Objects.equals(attr, BomBillEnum.MATERIEL.getAttr())) {
                importHelper.formatCommonProduct(titlePojoList, dataJson, rowValueList, fieldAttr, XbbRefTypeEnum.BOM_BILL.getCode(), corpid);
            } else if (Objects.equals(attr, BomBillEnum.VERSION.getAttr())) {
                JSONObject versionObject = new JSONObject();
                versionObject.put(StringConstant.VALUE, cellValue);
                versionObject.put(StringConstant.CHECKED, BasicConstant.ZERO);
                dataJson.put(attr, versionObject);
            } else if (Objects.equals(fieldType, FieldTypeEnum.SERIALNO.getType())) {
                formDataAddDTO.setSerialNo(Objects.toString(cellValue, ""));
            } else if (Objects.equals(fieldType, FieldTypeEnum.SUB_FORM.getType())) {
                importHelper.formatSubFormValue4Import(rowValueList, titlePojoList, importFormDataDTO, fieldAttr, dataJson);
            } else {
                if (Objects.isNull(cellValue) || StringUtil.isEmpty(cellValue.toString())) {
                    continue;
                }
                if (ImportHelper.commonHandleFieldType.contains(fieldAttr.getFieldType())) {
                    importHelper.formatCommonField(dataJson, fieldAttr, cellValue);
                } else if (Objects.equals(fieldType, FieldTypeEnum.LINK_DATA.getType())) {
                    importHelper.formatLinkData(cellValue, fieldAttr, dataJson);
                } else if (Objects.equals(fieldType, FieldTypeEnum.LINK_DATA_MULTI.getType())) {
                    importHelper.formatLinkDataMulti(cellValue, importFormDataDTO, fieldAttr, dataJson);
                } else {
                    dataJson.put(attr, cellValue);
                }
            }
        }
        formDataAddDTO.setDataList(dataJson);
        return formDataAddDTO;
    }

    @Override
    public void formatExportValue(List<PaasFormDataEntityExt> paasFormDataESList, FormDataListDTO formDataListDTO, List<FieldAttrEntityForImport> fieldAttrList) throws XbbException {
        List<Long> idList = new ArrayList<>();
        paasFormDataESList.forEach(item -> idList.add(item.getDataId()));

        // 关联产品map
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put(ParameterConstant.CORPID, formDataListDTO.getCorpid());
        params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        params.put("bomIdIn", idList);
        params.put("orderByStr","sort");
        List<BomProductEntity> bomProductList = bomProductModel.findEntitys(params);
        Set<Long> productIdIn = new HashSet<>();
        Map<Long, List<BomProductEntity>> materialProductMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, BomProductEntity> finishProductMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        bomProductList.forEach(item -> {
            productIdIn.add(item.getProductId());
            Long refId = item.getBomId();
            if (Objects.equals(item.getType(), 2)) {
                if (materialProductMap.containsKey(refId)) {
                    materialProductMap.get(refId).add(item);
                } else {
                    List<BomProductEntity> productEntityList = new ArrayList<>();
                    productEntityList.add(item);
                    materialProductMap.put(refId, productEntityList);
                }
            } else {
                finishProductMap.put(refId, item);
            }
        });

        // 所有产品map
        params.clear();
        params.put(ParameterConstant.CORPID, formDataListDTO.getCorpid());
        params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        params.put("idIn", productIdIn);
        List<ProductEntityExt> productList = productModel.findEntitys(params);
        Map<Long, ProductEntityExt> productMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        productIdIn.clear();
        productList.forEach(item -> {
            productMap.put(item.getId(), item);
            productIdIn.add(item.getData().getLong(ProductEnum.PARENT_ID.getAttr()));
        });
        params.clear();
        params.put(ParameterConstant.CORPID, formDataListDTO.getCorpid());
        params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        params.put("idIn", productIdIn);
        List<ProductEntityExt> parentProductList = productModel.findEntitys(params);
        parentProductList.forEach(item -> productMap.put(item.getId(), item));

        // 成品 物料字段解释
        FieldAttrEntityForImport productFieldAttr = new FieldAttrEntityForImport();
        FieldAttrEntityForImport materialFieldAttr = new FieldAttrEntityForImport();
        for (FieldAttrEntityForImport fieldAttr : fieldAttrList) {
            if (Objects.equals(fieldAttr.getAttr(), BomBillEnum.PRODUCT.getAttr())) {
                productFieldAttr = fieldAttr;
            } else if (Objects.equals(fieldAttr.getAttr(), BomBillEnum.MATERIEL.getAttr())) {
                materialFieldAttr = fieldAttr;
            }
        }

        Map<String, MultiUnitItemPoJo> groupBaseUnitStringMap = relativeProductHelp.getGroupBaseUnitStringMap(formDataListDTO.getCorpid());

        // 暂时只处理产品
        for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataESList) {
            JSONObject formDataObj = paasFormDataEntityExt.getData();
            Long dataId = paasFormDataEntityExt.getDataId();

            BomProductEntity finishProduct = finishProductMap.get(dataId);
            List<BomProductEntity> finishProductEntityList = new ArrayList<>();
            if (Objects.nonNull(finishProduct)) {
                finishProductEntityList.add(finishProduct);
            }
            JSONArray finishProductArray = new JSONArray();
            for (BomProductEntity finishProductEntity : finishProductEntityList) {
                Long productId = finishProductEntity.getProductId();
                Double num = finishProductEntity.getProductNum();
                // 产品信息转换
                JSONObject productObj = finishProductEntity.getData() == null ? new JSONObject() : finishProductEntity.getData();
                importHelper.formatProduct4Export(productMap, null, productId, num, null, productObj);
                productObj.put(BomFinishProductEnum.MEMO.getAttr(), finishProductEntity.getMemo());
                if (Objects.nonNull(finishProductEntity.getData()) && Objects.nonNull(finishProductEntity.getData().get(ProductEnum.UNIT.getAttr())) && !StringUtil.isEmpty(finishProductEntity.getData().get(ProductEnum.UNIT.getAttr()).toString())){
                    if (StringUtil.isDigital(finishProductEntity.getData().get(ProductEnum.UNIT.getAttr()).toString())){
                        Long unitId = Long.valueOf(finishProductEntity.getData().get(ProductEnum.UNIT.getAttr()).toString());
                        if (unitId > ProductConstant.MAX_SINGLE_UNIT_VALUE) {
                            finishProductEntity.getData().put(ProductEnum.ENABLE_MULTI_UNIT.getSaasAttr(), BasicConstant.ONE);
                        }
                    }
                }
                if (Objects.equals(productObj.getInteger(ProductEnum.ENABLE_MULTI_UNIT.getAttr()), BasicConstant.ONE)){
                    productObj.put(ProductEnum.UNIT.getAttr(), groupBaseUnitStringMap.getOrDefault(productObj.getString(ProductEnum.UNIT.getAttr()), new MultiUnitItemPoJo()).getBaseValue());
                    finishProductEntity.setProductUnit(productObj.getString(ProductEnum.UNIT.getAttr()));
                }
                finishProductArray.add(productObj);
            }
            formDataObj.put(productFieldAttr.getAttr(), finishProductArray);

            List<BomProductEntity> materialProductEntityList = materialProductMap.get(dataId);
            if (Objects.isNull(materialProductEntityList)) {
                materialProductEntityList = new ArrayList<>();
            }
            JSONArray materialProductArray = new JSONArray();
            for (BomProductEntity materialProductEntity : materialProductEntityList) {
                if (Objects.isNull(materialProductEntity)) {
                    continue;
                }
                Long productId = materialProductEntity.getProductId();
                Double num = materialProductEntity.getProductNum();
                Double attritionRate = materialProductEntity.getAttritionRate();
                // 产品信息转换
                JSONObject productObj = materialProductEntity.getData() == null ? new JSONObject() : materialProductEntity.getData();
                importHelper.formatProduct4Export(productMap, null, productId, num, null, productObj);
                productObj.put(BomMaterielProductEnum.LOSS_RATE.getAttr(), attritionRate);
                productObj.put(BomMaterielProductEnum.MEMO.getAttr(), materialProductEntity.getMemo());
                if (Objects.equals(productObj.getInteger(ProductEnum.ENABLE_MULTI_UNIT.getAttr()), BasicConstant.ONE)){
                    productObj.put(ProductEnum.UNIT.getAttr(), groupBaseUnitStringMap.getOrDefault(productObj.getString(ProductEnum.UNIT.getAttr()), new MultiUnitItemPoJo()).getBaseValue());
                    materialProductEntity.setProductUnit(productObj.getString(ProductEnum.UNIT.getAttr()));
                }
                materialProductArray.add(productObj);
            }
            formDataObj.put(materialFieldAttr.getAttr(), materialProductArray);
        }
    }


    @Override
    public void updateBatchByBusinessRule(BomUpdateByBusinessRuleDTO bomUpdateByBusinessRuleDTO) throws XbbException {
        try {
            String corpid = bomUpdateByBusinessRuleDTO.getCorpid();
            List<PaasFormDataEntityExt> formDataList = bomUpdateByBusinessRuleDTO.getFormDataList();
            List<UpdateDataEntity> updateList = ExplainUtil.getUpdateValueByBusinessRule(formDataList, corpid, bomUpdateByBusinessRuleDTO.getOperations());

            if (!updateList.isEmpty()) {
                bomBillModel.updateBatch(updateList, corpid);
                RuleBusinessLogDTO businessLogDTO = new RuleBusinessLogDTO();
                BeanUtil.copyProperties(bomUpdateByBusinessRuleDTO, businessLogDTO);
                businessLogDTO.setFormDataList(formDataList);
                ruleBusinessLogger.writeLog(businessLogDTO, updateList);
            }
        } catch (Exception e) {
            LOG.error("bomBillService.updateFormDataByBusinessRule根据业务规则更新数据出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    @Override
    public ProductSummaryVO summaryProductList(BusinessProductListDTO businessProductListDTO) throws XbbException {
        // 获取参数
        String corpid = businessProductListDTO.getCorpid();
        Long dataId = businessProductListDTO.getDataId();
        String attr = businessProductListDTO.getAttr();
        Map<String, Object> modelMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        modelMap.put(ParameterConstant.CORPID, corpid);
        modelMap.put("bomId", dataId);
        modelMap.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        if (Objects.equals(attr, BomBillEnum.PRODUCT.getAttr())) {
            modelMap.put(ParameterConstant.TYPE, 1);
        } else if (Objects.equals(attr, BomBillEnum.MATERIEL.getAttr())) {
            modelMap.put(ParameterConstant.TYPE, 2);
        }
        modelMap.put("columns", "product_num");
        List<BomProductEntity> bomProductEntities = bomProductModel.findEntitys(modelMap);

        ProductSummaryVO businessProductListVO = new ProductSummaryVO();

        Double num = 0D;
        for (BomProductEntity bomProductEntity : bomProductEntities) {
            Double productNum = bomProductEntity.getProductNum() != null ? bomProductEntity.getProductNum(): 0D;
            num = Arith.add(num, productNum);
        }
        Integer productSize = bomProductEntities.size();
        String summaryInfo = String.format(I18nMessageUtil.getMessage(StringConstant.PRODUCTS_TYPE_NUM), productSize, Arith.doubleToBigDecimal(num));
        businessProductListVO.setSummaryInfo(summaryInfo);
        return businessProductListVO;
    }

    private List<FieldAttrEntity> getHead(Boolean nameEnable, List<FieldAttrEntity> explainList) {
        List<BomBillEnum> headList = Arrays.asList(BomBillEnum.SHEET_NO, BomBillEnum.VERSION, BomBillEnum.PRODUCT_NAME_HIDE, BomBillEnum.PRODUCT_NO, BomBillEnum.PRODUCT_SPECIFICATION);
        Map<String, FieldAttrEntity> explainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        explainList.forEach(item->{
            explainMap.put(item.getAttr(), item);
        });
        /*----------表头--------------------------*/
        List<FieldAttrEntity> headerArray = new ArrayList<>();
        // BOM编号
        for (BomBillEnum item : headList) {
            if (!nameEnable && BomBillEnum.NAME.getAttr().equals(item.getAttr())) {
                // 启用，BOM名称
                continue;
            }
            if (explainMap.containsKey(item.getAttr())) {
                FieldAttrEntity fieldAttrEntity = explainMap.get(item.getAttr());
                if (Objects.equals(fieldAttrEntity.getAttr(), BomBillEnum.PRODUCT_NAME_HIDE.getAttr())) {
                    fieldAttrEntity.setAttrName(BomBillEnum.PRODUCT.getAttrName());
                }
                headerArray.add(fieldAttrEntity);
            }
        }
        return headerArray;
    }


    private List<PaasFormDataEntity> getProductIdIn(String corpid, List<Long> categoryIdInList) throws XbbException {
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        String point = StringConstant.POINT;
        String dataPoint = StringConstant.JSON_DATA + point;
        if (!categoryIdInList.isEmpty()) {
            boolQueryBuilder.filter(termsQuery(dataPoint + ProductEnum.CATEGORY_ID.getAttr(), categoryIdInList));
        }
        boolQueryBuilder.filter(termQuery(StringConstant.CORPID + point +StringConstant.KEY_WORD, corpid));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        boolQueryBuilder.mustNot(termQuery(dataPoint + ProductEnum.PARENT_ID.getAttr(), 0));
        List<String> fieldList = new ArrayList<>();
        fieldList.add(StringConstant.DATA_ID);
        fieldList.add(ProductEnum.getAttrConnectData(ProductEnum.SPECIFICATION_LINK_TEXT));
        List<PaasFormDataEntity> formDataList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_PRODUCT, boolQueryBuilder, PaasFormDataEntity.class, fieldList);
        if (Objects.isNull(formDataList)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return formDataList;
    }

    private List<Object> getBomIdIn(String corpid, List<String> userIdIn) throws XbbException{
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del", DelEnum.NORMAL.getDel());
        param.put("userIdIn", userIdIn);
        List<BomUserEntity> bomUserList = bomUserModel.findEntitys(param);
        if (Objects.isNull(bomUserList)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        List<Object> bomIdIn = new ArrayList<>();
        bomUserList.forEach(item->{
            bomIdIn.add(item.getDataId());
        });
        return bomIdIn;
    }
    /**
     * 批量更新
     * @param bomUpdateBatchDTO
     * @throws XbbException
     */
    private void updateBatch(BomUpdateBatchDTO bomUpdateBatchDTO) throws XbbException {
        try {
            String corpid = bomUpdateBatchDTO.getCorpid();
            if(Objects.nonNull(bomUpdateBatchDTO.getBomList())
                    && !bomUpdateBatchDTO.getBomList().isEmpty()) {
                List<UpdateDataEntity> list = new ArrayList<>();
                bomUpdateBatchDTO.getBomList().forEach((item)->{
                    list.add(ExplainUtil.getUpdateData(item.getId(), item.getData(), corpid));
                });
                if(!list.isEmpty()) {
                    bomBillModel.updateBatch(list, corpid);
                }
            }
        } catch (Exception e) {
            LOG.error("bomBillService.updateBatch 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }





    @Override
    public PagingProductVO getPagingProduct(PagingProductDTO pagingProductDTO) throws XbbException {
        PagingProductVO pagingProductVO = new PagingProductVO();
        Map<String, Object> modelMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        modelMap.put(ParameterConstant.CORPID, pagingProductDTO.getCorpid());
        modelMap.put(ParameterConstant.BOM_ID, pagingProductDTO.getDataId());
        modelMap.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        modelMap.put(ParameterConstant.PAGE,  pagingProductDTO.getPage());
        modelMap.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
        if (Objects.equals(pagingProductDTO.getAttr(), BomBillEnum.PRODUCT.getAttr())) {
            modelMap.put(ParameterConstant.TYPE, 1);
        } else if (Objects.equals(pagingProductDTO.getAttr(), BomBillEnum.MATERIEL.getAttr())) {
            modelMap.put(ParameterConstant.TYPE, 2);
        }
        PageHelper pageHelper = PageHelperUtil.getPageHelper(modelMap, bomProductModel, pagingProductDTO.getPageSize());
        List<BomProductEntity> bomProductEntityList = (List<BomProductEntity>) PageHelperUtil.getEntityList(modelMap, pageHelper, bomProductModel);
        if (pagingProductDTO.getUpdateDataTypeEnum().isDetail()) {
            DetailProductVO detailProductVO = formatProduct4DetailShow(bomProductEntityList, pagingProductDTO);
            pagingProductVO.setProductDataArr(detailProductVO.getProductDataArr());
        }
        pagingProductVO.setPageHelper(pageHelper);
        return pagingProductVO;
    }

    public DetailProductVO formatProduct4DetailShow(List<BomProductEntity> bomProductEntityList, PagingProductDTO pagingProductDTO) throws XbbException{
        DetailProductVO detailProductVO = new DetailProductVO();
        Set<Long> productIds = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (BomProductEntity bomProductEntity : bomProductEntityList) {
            productIds.add(bomProductEntity.getProductId());
        }
        String corpid = pagingProductDTO.getCorpid();
        JSONArray productArray = new JSONArray();
        Map<Long, PaasFormDataEntityExt> productMap = productService.getProductMapByIdIn(productIds, corpid, DelEnum.NORMAL);
        PaasFormExplainEntity productExplains = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.PRODUCT.getCode(), corpid);
        if (Objects.isNull(productExplains)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        Map<String, FieldAttrEntity> productExplainMap = ExplainUtil.getExplainMap(productExplains.getExplains(), null);
        for (BomProductEntity bomProductEntity : bomProductEntityList) {
            if (Objects.nonNull(bomProductEntity.getBusinessUnit())) {
                bomProductEntity.setProductNum(Arith.div(bomProductEntity.getProductNum(), bomProductEntity.getRate()));
                bomProductEntity.setProductUnit(bomProductEntity.getBusinessUnit().toString());
            }
            PaasFormDataEntityExt paasFormDataEntityExt = productMap.get(bomProductEntity.getProductId());
            JSONObject json = new JSONObject();
            if (Objects.nonNull(bomProductEntity.getData())) {
                json = bomProductEntity.getData();
            }
            for (BomMaterielProductEnum bomMaterielProductEnum : BomMaterielProductEnum.values()) {
                if (!UpdateDataTypeEnum.DETAIL.formatShow(bomMaterielProductEnum.getShowType())) {
                    continue;
                }
                String attr = bomMaterielProductEnum.getAttr();
                switch (bomMaterielProductEnum) {
                    case PRODUCT:
                        json.put(attr, bomProductEntity.getProductId());
                        break;
                    case NUM:
                        json.put(attr, bomProductEntity.getProductNum());
                        break;
                    case MEMO:
                        json.put(attr, bomProductEntity.getMemo());
                        break;
                    case UNIT:
                        json.put(attr, bomProductEntity.getProductUnit());
                        break;
                    case LOSS_RATE:
                        json.put(attr, bomProductEntity.getAttritionRate());
                        break;
                    default:
                        break;
                }
            }
            json.put(BusinessConstant.PRODUCT_SUB_ID, bomProductEntity.getId());
            productArray.add(json);
        }
        detailProductVO.setProductDataArr(productArray);
        return detailProductVO;
    }

    @Override
    public Map<Long,String> getBomBillNameMap(List<Long> handoverIdSet, String corpid) throws XbbException {
        Map<Long,String> bomBillNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (handoverIdSet.isEmpty()){
            return bomBillNameMap;
        }
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
        boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(),handoverIdSet));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_BOM.getType()));
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(boolQueryBuilder);
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 1, handoverIdSet.size());
        SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_BOM.getIndex());
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntity> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest,searchRequest,PaasFormDataEntity.class);
        for (PaasFormDataEntity entity : esEntities.getContent()){
            bomBillNameMap.put(entity.getDataId(),entity.getData().getString(BomBillEnum.NAME.getAttr()));
        }
        return bomBillNameMap;
    }
    @Override
    public void updateBatchLabelAttr(AddLabelDTO addLabelDTO, List<PaasFormDataEntityExt> addBatchList, Boolean addOrDelete) throws XbbException {
        BomUpdateBatchDTO bomUpdateBatchDTO = new BomUpdateBatchDTO();
        BeanUtil.copyProperties(addLabelDTO, bomUpdateBatchDTO);
        List<BomUpdateDTO> bomList = new ArrayList<>();
        addBatchList.forEach(item->{
            BomUpdateDTO bomUpdateDTO = new BomUpdateDTO();
            bomUpdateDTO.setData(item.getData());
            bomUpdateDTO.setId(item.getId());
            bomList.add(bomUpdateDTO);
        });
        bomUpdateBatchDTO.setBomList(bomList);
        updateBatch(bomUpdateBatchDTO);

    }

    @Override
    public void afterSaveForWorkflow(SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        String corpid = saasFormSaveDTO.getCorpid();
        PaasFormDataEntity newEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
        Long bomId = newEntity.getId();

        // 团队保存
        teamDataHelp.saveUserTeam(saasFormSaveDTO.getSaasNeedRedundantAttrPoJo(), bomId, saasFormSaveDTO.getNewPaasFormDataEntity(), saasFormSaveDTO.getIsImport(),true);

//        userTeamService.saveUserTeam(saasFormSaveDTO);
        // 保存bom单关联产品
        JSONObject dataList = newEntity.getData();
        Boolean productCanSee = saasFormSaveDTO.getSaasNeedRedundantAttrPoJo().getAttrCanSee(BomBillEnum.PRODUCT.getAttr());
        Boolean materielCanSee = saasFormSaveDTO.getSaasNeedRedundantAttrPoJo().getAttrCanSee(BomBillEnum.MATERIEL.getAttr());
        saveProduct2(dataList,corpid,bomId,productCanSee,materielCanSee);
    }

    @Override
    public void afterSaveForUpdateWorkflow(SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        String corpid = saasFormSaveDTO.getCorpid();
        PaasFormDataEntity newEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
        Long bomId = newEntity.getId();

        // 团队保存
        teamDataHelp.saveUserTeam(saasFormSaveDTO.getSaasNeedRedundantAttrPoJo(), bomId, saasFormSaveDTO.getNewPaasFormDataEntity(), saasFormSaveDTO.getIsImport(), true);

        // 保存bom单关联产品
        JSONObject dataList = newEntity.getData();
        Boolean productCanSee = saasFormSaveDTO.getSaasNeedRedundantAttrPoJo().getAttrCanSee(BomBillEnum.PRODUCT.getAttr());
        Boolean materielCanSee = saasFormSaveDTO.getSaasNeedRedundantAttrPoJo().getAttrCanSee(BomBillEnum.MATERIEL.getAttr());
        saveProduct2(dataList,corpid,bomId,productCanSee,materielCanSee);
    }
}
